@cannyminds/dms-file-viewers 0.14.0 → 0.15.0

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.
Files changed (97) hide show
  1. package/dist/chunk-42VHR3EK.mjs +714 -0
  2. package/dist/chunk-42VHR3EK.mjs.map +1 -0
  3. package/dist/{chunk-J3JKVSAM.js → chunk-AYVTSFZA.js} +2 -1
  4. package/dist/chunk-AYVTSFZA.js.map +1 -0
  5. package/dist/chunk-C4L2R2QY.mjs +277 -0
  6. package/dist/chunk-C4L2R2QY.mjs.map +1 -0
  7. package/dist/chunk-DBXSX2B6.js +277 -0
  8. package/dist/chunk-DBXSX2B6.js.map +1 -0
  9. package/dist/chunk-DPSRGULQ.mjs +247 -0
  10. package/dist/chunk-DPSRGULQ.mjs.map +1 -0
  11. package/dist/chunk-FK6RYOAZ.mjs +297 -0
  12. package/dist/chunk-FK6RYOAZ.mjs.map +1 -0
  13. package/dist/chunk-FZVXQGA7.mjs +466 -0
  14. package/dist/chunk-FZVXQGA7.mjs.map +1 -0
  15. package/dist/chunk-GSRAK2YV.js +266 -0
  16. package/dist/chunk-GSRAK2YV.js.map +1 -0
  17. package/dist/chunk-HYRQBGAX.js +466 -0
  18. package/dist/chunk-HYRQBGAX.js.map +1 -0
  19. package/dist/chunk-RKDOWWQD.js +247 -0
  20. package/dist/chunk-RKDOWWQD.js.map +1 -0
  21. package/dist/chunk-TMAHQICY.mjs +1842 -0
  22. package/dist/chunk-TMAHQICY.mjs.map +1 -0
  23. package/dist/chunk-VBJVOB45.mjs +266 -0
  24. package/dist/chunk-VBJVOB45.mjs.map +1 -0
  25. package/dist/{chunk-DFBVN4MO.mjs → chunk-WR5SJ3LM.mjs} +2 -1
  26. package/dist/chunk-WR5SJ3LM.mjs.map +1 -0
  27. package/dist/chunk-XSXOX4MV.js +297 -0
  28. package/dist/chunk-XSXOX4MV.js.map +1 -0
  29. package/dist/chunk-XWWMHRVU.js +1842 -0
  30. package/dist/chunk-XWWMHRVU.js.map +1 -0
  31. package/dist/chunk-YU535XRJ.js +714 -0
  32. package/dist/chunk-YU535XRJ.js.map +1 -0
  33. package/dist/components/viewers/AudioViewer.d.mts +1 -1
  34. package/dist/components/viewers/AudioViewer.d.ts +1 -1
  35. package/dist/components/viewers/AudioViewer.js +3 -3
  36. package/dist/components/viewers/AudioViewer.mjs +2 -2
  37. package/dist/components/viewers/DefaultViewer.d.mts +1 -1
  38. package/dist/components/viewers/DefaultViewer.d.ts +1 -1
  39. package/dist/components/viewers/DefaultViewer.js +3 -3
  40. package/dist/components/viewers/DefaultViewer.mjs +2 -2
  41. package/dist/components/viewers/ImageViewer.d.mts +1 -1
  42. package/dist/components/viewers/ImageViewer.d.ts +1 -1
  43. package/dist/components/viewers/ImageViewer.js +3 -3
  44. package/dist/components/viewers/ImageViewer.mjs +2 -2
  45. package/dist/components/viewers/PDFViewer.d.mts +1 -1
  46. package/dist/components/viewers/PDFViewer.d.ts +1 -1
  47. package/dist/components/viewers/PDFViewer.js +3 -3
  48. package/dist/components/viewers/PDFViewer.mjs +2 -2
  49. package/dist/components/viewers/TIFFViewer.d.mts +1 -1
  50. package/dist/components/viewers/TIFFViewer.d.ts +1 -1
  51. package/dist/components/viewers/TIFFViewer.js +3 -3
  52. package/dist/components/viewers/TIFFViewer.mjs +2 -2
  53. package/dist/components/viewers/TextViewer.d.mts +1 -1
  54. package/dist/components/viewers/TextViewer.d.ts +1 -1
  55. package/dist/components/viewers/TextViewer.js +3 -3
  56. package/dist/components/viewers/TextViewer.mjs +2 -2
  57. package/dist/components/viewers/VideoViewer.d.mts +1 -1
  58. package/dist/components/viewers/VideoViewer.d.ts +1 -1
  59. package/dist/components/viewers/VideoViewer.js +3 -3
  60. package/dist/components/viewers/VideoViewer.mjs +2 -2
  61. package/dist/index.d.mts +2 -2
  62. package/dist/index.d.ts +2 -2
  63. package/dist/index.js +9 -9
  64. package/dist/index.mjs +8 -8
  65. package/dist/{types-DNrkDJdK.d.mts → types-DxRCbIFP.d.mts} +4 -2
  66. package/dist/{types-DNrkDJdK.d.ts → types-DxRCbIFP.d.ts} +4 -2
  67. package/package.json +1 -1
  68. package/dist/chunk-7QRYWFCO.js +0 -639
  69. package/dist/chunk-7QRYWFCO.js.map +0 -1
  70. package/dist/chunk-7R2KG3PE.mjs +0 -210
  71. package/dist/chunk-7R2KG3PE.mjs.map +0 -1
  72. package/dist/chunk-CFYOPDCG.mjs +0 -235
  73. package/dist/chunk-CFYOPDCG.mjs.map +0 -1
  74. package/dist/chunk-D74R4IKW.mjs +0 -341
  75. package/dist/chunk-D74R4IKW.mjs.map +0 -1
  76. package/dist/chunk-DFBVN4MO.mjs.map +0 -1
  77. package/dist/chunk-EXZCEYLI.js +0 -247
  78. package/dist/chunk-EXZCEYLI.js.map +0 -1
  79. package/dist/chunk-J3JKVSAM.js.map +0 -1
  80. package/dist/chunk-NXVIRFGL.mjs +0 -247
  81. package/dist/chunk-NXVIRFGL.mjs.map +0 -1
  82. package/dist/chunk-P2VNW6OE.mjs +0 -180
  83. package/dist/chunk-P2VNW6OE.mjs.map +0 -1
  84. package/dist/chunk-P5FH7LK7.mjs +0 -639
  85. package/dist/chunk-P5FH7LK7.mjs.map +0 -1
  86. package/dist/chunk-PZJSY6OF.mjs +0 -1736
  87. package/dist/chunk-PZJSY6OF.mjs.map +0 -1
  88. package/dist/chunk-RVHIXSUP.js +0 -235
  89. package/dist/chunk-RVHIXSUP.js.map +0 -1
  90. package/dist/chunk-TGVFAAIP.js +0 -341
  91. package/dist/chunk-TGVFAAIP.js.map +0 -1
  92. package/dist/chunk-VOLQW3NF.js +0 -1736
  93. package/dist/chunk-VOLQW3NF.js.map +0 -1
  94. package/dist/chunk-VSGX22FQ.js +0 -180
  95. package/dist/chunk-VSGX22FQ.js.map +0 -1
  96. package/dist/chunk-WCAXWJE7.js +0 -210
  97. package/dist/chunk-WCAXWJE7.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/viewers/PDFViewer.tsx","../src/components/viewers/pdf/StablePDFViewer.tsx","../src/components/viewers/pdf/PDFToolbar.tsx","../src/components/viewers/pdf/PDFHeader.tsx","../src/components/viewers/pdf/SearchSidebar.tsx","../src/components/viewers/pdf/PasswordDialog.tsx"],"sourcesContent":["import React, {\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useState,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { FileViewerProps } from \"../../types\";\r\nimport { getFileExtension } from \"../../utils/fileUtils\";\r\nimport { mergeToolbarConfig } from \"../../utils/toolbarUtils\";\r\nimport {\r\n StablePDFViewer,\r\n PDFToolbar,\r\n PDFHeader,\r\n SearchSidebar,\r\n PasswordDialog,\r\n toolbarStyles,\r\n type CannyMindsPDFViewerRef,\r\n} from \"./pdf\";\r\n\r\ntype LoadingState = \"idle\" | \"loading\" | \"ready\" | \"error\";\r\n\r\n/**\r\n * IMPORTANT: The @cannyminds/pdf-viewer navigation API is not fully implemented.\r\n * Methods like getCurrentPage(), getTotalPages(), goToPage() return hardcoded values.\r\n * This component implements custom page tracking using DOM inspection and search detection.\r\n */\r\n\r\ninterface PDFViewerContentProps extends FileViewerProps {\r\n sourceDescription: string;\r\n}\r\n\r\nexport interface PDFViewerMethods {\r\n zoomIn: () => void;\r\n zoomOut: () => void;\r\n setZoom: (level: number) => void;\r\n resetZoom: () => void;\r\n getZoom: () => number;\r\n goToPage: (page: number) => void;\r\n getCurrentPage: () => number;\r\n getTotalPages: () => number;\r\n nextPage: () => void;\r\n previousPage: () => void;\r\n goToFirstPage: () => void;\r\n goToLastPage: () => void;\r\n searchText: (keyword: string) => Promise<any>;\r\n nextResult: () => number;\r\n previousResult: () => number;\r\n goToResult: (index: number) => number;\r\n stopSearch: () => void;\r\n getSearchState: () => any;\r\n getSelectedText: () => string;\r\n clearSelection: () => void;\r\n rotateForward: () => void;\r\n rotateBackward: () => void;\r\n getRotation: () => number;\r\n}\r\n\r\nconst PDFViewerContent = forwardRef<PDFViewerMethods, PDFViewerContentProps>(\r\n (props, ref) => {\r\n const {\r\n file,\r\n onLoad,\r\n onError,\r\n fileName,\r\n showPageCount = true,\r\n showPageNavigation = true,\r\n showZoomControls = true,\r\n showRotation = true,\r\n showDownload = true,\r\n showPrint = true,\r\n showSearch = true,\r\n showMetadata = true,\r\n showProperties = true,\r\n showTags = true,\r\n onMetadataClick,\r\n onPropertiesClick,\r\n onTagsClick,\r\n onDownloadClick,\r\n onPrintClick,\r\n initialSearchText,\r\n initialSearchPages,\r\n } = props;\r\n const [pdfBuffer, setPdfBuffer] = useState<ArrayBuffer | null>(null);\r\n const [state, setState] = useState<LoadingState>(\"idle\");\r\n const [error, setError] = useState<string | null>(null);\r\n const pdfViewerRef = useRef<CannyMindsPDFViewerRef>(null);\r\n\r\n // File info\r\n const resolvedFileName = useMemo(() => {\r\n if (fileName) return fileName;\r\n if (file instanceof File) return file.name;\r\n if (typeof file === \"string\") {\r\n const urlParts = file.split(\"/\");\r\n return urlParts[urlParts.length - 1] || \"document.pdf\";\r\n }\r\n return \"document.pdf\";\r\n }, [file, fileName]);\r\n\r\n const fileExtension = useMemo(\r\n () => getFileExtension(resolvedFileName),\r\n [resolvedFileName]\r\n );\r\n\r\n // Toolbar state\r\n const [currentPage, setCurrentPage] = useState(1);\r\n const [totalPages, setTotalPages] = useState(0);\r\n const [zoom, setZoom] = useState(100);\r\n const [searchQuery, setSearchQuery] = useState(\"\");\r\n const [isSearching, setIsSearching] = useState(false);\r\n const [pdfContainer, setPdfContainer] = useState<HTMLElement | null>(null);\r\n const [isSidebarOpen, setIsSidebarOpen] = useState(false);\r\n const [searchResults, setSearchResults] = useState<any[]>([]);\r\n const [currentSearchResultIndex, setCurrentSearchResultIndex] = useState(0);\r\n const [totalSearchResults, setTotalSearchResults] = useState(0);\r\n const [autoExecuteSearch, setAutoExecuteSearch] = useState(\r\n !!initialSearchText\r\n );\r\n const [isFullScreen, setIsFullScreen] = useState(false);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // Password dialog state\r\n const [isPasswordDialogOpen, setIsPasswordDialogOpen] = useState(false);\r\n const [passwordError, setPasswordError] = useState<string>(\"\");\r\n const [passwordResolve, setPasswordResolve] = useState<\r\n ((password: string | null) => void) | null\r\n >(null);\r\n\r\n const hasExecutedInitialSearch = useRef(false);\r\n\r\n const handleToggleFullScreen = useCallback(() => {\r\n if (!isFullScreen && containerRef.current?.requestFullscreen) {\r\n containerRef.current.requestFullscreen();\r\n setIsFullScreen(true);\r\n } else if (isFullScreen && document.exitFullscreen) {\r\n document.exitFullscreen();\r\n setIsFullScreen(false);\r\n }\r\n }, [isFullScreen]);\r\n\r\n // Handle sidebar close - clear all search state and highlighting\r\n const handleSidebarClose = useCallback(() => {\r\n setIsSidebarOpen(false);\r\n setSearchQuery(\"\");\r\n setSearchResults([]);\r\n setTotalSearchResults(0);\r\n setCurrentSearchResultIndex(0);\r\n pdfViewerRef.current?.search.stopSearch(); // Stop search to remove highlighting\r\n }, []);\r\n\r\n const toolbar = mergeToolbarConfig({\r\n showDownload,\r\n showPrint,\r\n showMetadata,\r\n showProperties,\r\n showTags,\r\n showRotation,\r\n onDownloadClick,\r\n onPrintClick,\r\n onMetadataClick,\r\n onPropertiesClick,\r\n onTagsClick,\r\n toolbarActions: props.toolbarActions,\r\n });\r\n\r\n // Create stable callback handlers to prevent re-renders\r\n const toolbarHandlers = useMemo(\r\n () => ({\r\n handleZoomIn: () => {\r\n pdfViewerRef.current?.zoom.zoomIn();\r\n requestAnimationFrame(() => {\r\n const zoomValue = pdfViewerRef.current?.zoom.getZoom();\r\n if (typeof zoomValue === \"number\") {\r\n setZoom(Math.round(zoomValue * 100));\r\n }\r\n });\r\n },\r\n handleZoomOut: () => {\r\n pdfViewerRef.current?.zoom.zoomOut();\r\n requestAnimationFrame(() => {\r\n const zoomValue = pdfViewerRef.current?.zoom.getZoom();\r\n if (typeof zoomValue === \"number\") {\r\n setZoom(Math.round(zoomValue * 100));\r\n }\r\n });\r\n },\r\n handleFitToWidth: () => {\r\n pdfViewerRef.current?.zoom.fitToWidth();\r\n requestAnimationFrame(() => {\r\n const zoomValue = pdfViewerRef.current?.zoom.getZoom();\r\n if (typeof zoomValue === \"number\") {\r\n setZoom(Math.round(zoomValue * 100));\r\n }\r\n });\r\n },\r\n handleFitToPage: () => {\r\n pdfViewerRef.current?.zoom.fitToPage();\r\n requestAnimationFrame(() => {\r\n const zoomValue = pdfViewerRef.current?.zoom.getZoom();\r\n if (typeof zoomValue === \"number\") {\r\n setZoom(Math.round(zoomValue * 100));\r\n }\r\n });\r\n },\r\n handlePreviousPage: () => {\r\n pdfViewerRef.current?.navigation.previousPage();\r\n requestAnimationFrame(() => {\r\n const current =\r\n pdfViewerRef.current?.navigation.getCurrentPage() || 1;\r\n setCurrentPage(current);\r\n });\r\n },\r\n handleNextPage: () => {\r\n pdfViewerRef.current?.navigation.nextPage();\r\n requestAnimationFrame(() => {\r\n const current =\r\n pdfViewerRef.current?.navigation.getCurrentPage() || 1;\r\n setCurrentPage(current);\r\n });\r\n },\r\n handleFirstPage: () => {\r\n pdfViewerRef.current?.navigation.goToFirstPage();\r\n requestAnimationFrame(() => {\r\n const current =\r\n pdfViewerRef.current?.navigation.getCurrentPage() || 1;\r\n setCurrentPage(current);\r\n });\r\n },\r\n handleLastPage: () => {\r\n pdfViewerRef.current?.navigation.goToLastPage();\r\n requestAnimationFrame(() => {\r\n const current =\r\n pdfViewerRef.current?.navigation.getCurrentPage() || 1;\r\n setCurrentPage(current);\r\n });\r\n },\r\n toggleSidebar: () => {\r\n if (isSidebarOpen) {\r\n // Closing sidebar - clear search state\r\n handleSidebarClose();\r\n } else {\r\n // Opening sidebar\r\n setIsSidebarOpen(true);\r\n }\r\n },\r\n handlePageInput: (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const value = e.target.value;\r\n if (/^\\d*$/.test(value)) {\r\n return;\r\n }\r\n const page = parseInt(value, 10);\r\n if (\r\n !isNaN(page) &&\r\n page >= 1 &&\r\n (totalPages === 0 || page <= totalPages)\r\n ) {\r\n pdfViewerRef.current?.navigation.goToPage(page);\r\n setCurrentPage(page);\r\n }\r\n },\r\n handlePageInputKeyPress: (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n if (e.key === \"Enter\") {\r\n const value = (e.target as HTMLInputElement).value;\r\n const page = parseInt(value, 10);\r\n if (\r\n !isNaN(page) &&\r\n page >= 1 &&\r\n (totalPages === 0 || page <= totalPages)\r\n ) {\r\n pdfViewerRef.current?.navigation.goToPage(page);\r\n setCurrentPage(page);\r\n }\r\n }\r\n },\r\n handleRotateLeft: () => {\r\n pdfViewerRef.current?.rotate?.rotateBackward();\r\n },\r\n handleRotateRight: () => {\r\n pdfViewerRef.current?.rotate?.rotateForward();\r\n },\r\n handleToggleFullScreen,\r\n }),\r\n [isSidebarOpen, totalPages, handleToggleFullScreen]\r\n );\r\n\r\n // Auto-execute initial search when PDF is ready\r\n useEffect(() => {\r\n console.log(\r\n \"came\",\r\n initialSearchText,\r\n pdfViewerRef.current,\r\n hasExecutedInitialSearch.current,\r\n \"state:\",\r\n state,\r\n \"totalPages:\",\r\n totalPages\r\n );\r\n\r\n // Skip if no search text or already executed\r\n if (!initialSearchText || hasExecutedInitialSearch.current) return;\r\n\r\n // Validate all prerequisites are met\r\n const isPDFReady = state === \"ready\";\r\n const isPagesInitialized = totalPages > 0;\r\n const isViewerAvailable = !!pdfViewerRef.current;\r\n const isSearchAPIReady = !!pdfViewerRef.current?.search?.searchText;\r\n\r\n const canExecuteSearch =\r\n isPDFReady &&\r\n isPagesInitialized &&\r\n isViewerAvailable &&\r\n isSearchAPIReady;\r\n\r\n if (!canExecuteSearch) return;\r\n\r\n // Mark as executed to prevent duplicate runs\r\n hasExecutedInitialSearch.current = true;\r\n\r\n // Small delay to ensure render completes and search index is stable\r\n const SEARCH_INITIALIZATION_DELAY = 100;\r\n\r\n setTimeout(() => {\r\n // Safety check: Verify search API is still available\r\n if (!pdfViewerRef.current?.search?.searchText) {\r\n console.warn(\r\n \"Search API became unavailable, skipping initial search\"\r\n );\r\n hasExecutedInitialSearch.current = false;\r\n return;\r\n }\r\n\r\n // Execute search after render completes\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(() => {\r\n setIsSidebarOpen(true);\r\n handleSidebarSearch(initialSearchText, initialSearchPages);\r\n setAutoExecuteSearch(false);\r\n });\r\n });\r\n }, SEARCH_INITIALIZATION_DELAY);\r\n }, [\r\n state,\r\n totalPages,\r\n pdfViewerRef.current,\r\n initialSearchText,\r\n initialSearchPages,\r\n ]);\r\n\r\n // Reset all state when file changes\r\n useEffect(() => {\r\n // Reset search state\r\n setSearchQuery(\"\");\r\n setSearchResults([]);\r\n setCurrentSearchResultIndex(0);\r\n setTotalSearchResults(0);\r\n setIsSearching(false);\r\n setIsSidebarOpen(false);\r\n hasExecutedInitialSearch.current = false;\r\n\r\n // Reset page state\r\n setCurrentPage(1);\r\n setTotalPages(0);\r\n setZoom(100);\r\n\r\n // Reset PDF state\r\n setState(\"idle\");\r\n setError(null);\r\n setPdfBuffer(null);\r\n }, [file]);\r\n\r\n // Track the PDF container for page detection using MutationObserver\r\n useEffect(() => {\r\n if (state !== \"ready\") return;\r\n\r\n const container = document.querySelector(\r\n '[data-pdf-viewer], .embedpdf-viewport, [role=\"document\"]'\r\n ) as HTMLElement;\r\n if (container) {\r\n setPdfContainer(container);\r\n return;\r\n }\r\n\r\n // Use MutationObserver to wait for container to appear in DOM\r\n const observer = new MutationObserver(() => {\r\n const foundContainer = document.querySelector(\r\n '[data-pdf-viewer], .embedpdf-viewport, [role=\"document\"]'\r\n ) as HTMLElement;\r\n if (foundContainer) {\r\n setPdfContainer(foundContainer);\r\n observer.disconnect();\r\n }\r\n });\r\n\r\n observer.observe(document.body, { childList: true, subtree: true });\r\n return () => observer.disconnect();\r\n }, [state]);\r\n\r\n // Initialize page count after PDF loads - using async polling with exponential backoff\r\n useEffect(() => {\r\n if (state !== \"ready\" || totalPages > 0) return;\r\n\r\n const initializePageCount = async () => {\r\n // Wait for viewer ref with exponential backoff\r\n const waitForViewer = async (\r\n maxAttempts = 10\r\n ): Promise<typeof pdfViewerRef.current> => {\r\n for (let i = 0; i < maxAttempts; i++) {\r\n if (pdfViewerRef.current) return pdfViewerRef.current;\r\n await new Promise((resolve) =>\r\n requestAnimationFrame(() =>\r\n setTimeout(resolve, Math.min(100 * Math.pow(2, i), 1000))\r\n )\r\n );\r\n }\r\n return null;\r\n };\r\n\r\n const viewer = await waitForViewer();\r\n if (!viewer) return;\r\n\r\n // Wait for pages to render using requestAnimationFrame\r\n await new Promise((resolve) => requestAnimationFrame(resolve));\r\n\r\n // Try navigation API first\r\n try {\r\n const count = viewer.navigation?.getTotalPages?.();\r\n if (count && count > 1) {\r\n setTotalPages(count);\r\n return;\r\n }\r\n } catch (e) {\r\n // Continue to fallback methods\r\n }\r\n\r\n // Fallback: Search for common character and count unique pages\r\n try {\r\n const results = await viewer.search?.searchText?.(\"e\");\r\n\r\n if (results?.results && results.results.length > 0) {\r\n const pageIndices = results.results\r\n .map((m: any) => m.pageIndex as number)\r\n .filter((idx: any): idx is number => typeof idx === \"number\");\r\n const count = Math.max(...pageIndices) + 1;\r\n viewer.search?.stopSearch?.();\r\n setTotalPages(count);\r\n return;\r\n }\r\n } catch (error) {\r\n // Continue to next method\r\n }\r\n\r\n // DOM inspection fallback - count rendered pages\r\n // Wait a bit for pages to render in DOM before checking\r\n await new Promise((resolve) => setTimeout(resolve, 200));\r\n\r\n try {\r\n const selectors = [\r\n \"[data-page-index]\",\r\n \"[data-page-number]\",\r\n \".embedpdf-page\",\r\n '[role=\"article\"]',\r\n \"canvas[data-page]\",\r\n \".react-pdf__Page\",\r\n ];\r\n\r\n for (const selector of selectors) {\r\n const pages = document.querySelectorAll(selector);\r\n if (pages.length > 0) {\r\n setTotalPages(pages.length);\r\n return;\r\n }\r\n }\r\n } catch (error) {\r\n // Continue to fallback\r\n }\r\n\r\n // If we still don't have a count, try one more time with navigation API\r\n try {\r\n const count = viewer.navigation?.getTotalPages?.();\r\n if (count && count > 0) {\r\n setTotalPages(count);\r\n return;\r\n }\r\n } catch (e) {\r\n // Final fallback\r\n }\r\n\r\n // Only set to 1 as last resort (this should rarely happen)\r\n console.warn(\r\n \"Could not determine total pages, using fallback value of 1\"\r\n );\r\n setTotalPages(1);\r\n };\r\n\r\n initializePageCount();\r\n }, [state, totalPages]);\r\n\r\n // Auto-execute search when initialSearchText is provided via props\r\n // useEffect(() => {\r\n // if (state !== 'ready' || !autoExecuteSearch || !initialSearchText) return;\r\n\r\n // // Use requestIdleCallback for better performance, fallback to rAF\r\n // const scheduleSearch = (callback: () => void) => {\r\n // if ('requestIdleCallback' in window) {\r\n // requestIdleCallback(callback, { timeout: 2000 });\r\n // } else {\r\n // requestAnimationFrame(() => setTimeout(callback, 0));\r\n // }\r\n // };\r\n\r\n // scheduleSearch(() => {\r\n // if (!pdfViewerRef.current) return;\r\n\r\n // setIsSidebarOpen(true);\r\n // setSearchQuery(initialSearchText);\r\n // handleSidebarSearch(initialSearchText, initialSearchPages);\r\n // setAutoExecuteSearch(false);\r\n // });\r\n // }, [state, autoExecuteSearch, initialSearchText, initialSearchPages]);\r\n\r\n // Update page info and search state periodically\r\n useEffect(() => {\r\n if (state === \"ready\" && pdfViewerRef.current) {\r\n const updateInfo = () => {\r\n const current =\r\n pdfViewerRef.current?.navigation.getCurrentPage() || 1;\r\n const total = pdfViewerRef.current?.navigation.getTotalPages() || 0;\r\n const zoomValue = pdfViewerRef.current?.zoom.getZoom();\r\n const currentSearchState =\r\n pdfViewerRef.current?.search.getSearchState();\r\n\r\n setCurrentPage(current);\r\n\r\n // Update total pages if we got a valid count\r\n if (total > 0 && total !== totalPages) {\r\n setTotalPages(total);\r\n }\r\n\r\n if (typeof zoomValue === \"number\") {\r\n setZoom(Math.round(zoomValue * 100));\r\n }\r\n };\r\n\r\n updateInfo();\r\n const interval = setInterval(updateInfo, 300);\r\n return () => clearInterval(interval);\r\n }\r\n }, [state, totalPages]);\r\n\r\n // Expose methods through ref\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n zoomIn: () => {\r\n pdfViewerRef.current?.zoom.zoomIn();\r\n updateZoomDisplay();\r\n },\r\n zoomOut: () => {\r\n pdfViewerRef.current?.zoom.zoomOut();\r\n updateZoomDisplay();\r\n },\r\n setZoom: (level: number) => {\r\n pdfViewerRef.current?.zoom.setZoom(level);\r\n updateZoomDisplay();\r\n },\r\n resetZoom: () => {\r\n pdfViewerRef.current?.zoom.resetZoom();\r\n updateZoomDisplay();\r\n },\r\n getZoom: () => {\r\n const zoom = pdfViewerRef.current?.zoom.getZoom();\r\n return typeof zoom === \"number\" ? zoom : 1.0;\r\n },\r\n goToPage: (page: number) => {\r\n pdfViewerRef.current?.navigation.goToPage(page);\r\n setCurrentPage(page);\r\n },\r\n getCurrentPage: () =>\r\n pdfViewerRef.current?.navigation.getCurrentPage() || 1,\r\n getTotalPages: () =>\r\n pdfViewerRef.current?.navigation.getTotalPages() || 0,\r\n nextPage: () => {\r\n pdfViewerRef.current?.navigation.nextPage();\r\n updatePageDisplay();\r\n },\r\n previousPage: () => {\r\n pdfViewerRef.current?.navigation.previousPage();\r\n updatePageDisplay();\r\n },\r\n goToFirstPage: () => {\r\n pdfViewerRef.current?.navigation.goToFirstPage();\r\n updatePageDisplay();\r\n },\r\n goToLastPage: () => {\r\n pdfViewerRef.current?.navigation.goToLastPage();\r\n updatePageDisplay();\r\n },\r\n searchText: async (keyword: string) => {\r\n setIsSearching(true);\r\n const results = await pdfViewerRef.current?.search.searchText(\r\n keyword\r\n );\r\n setIsSearching(false);\r\n setSearchQuery(keyword);\r\n // Search state will be updated by the interval\r\n return results;\r\n },\r\n nextResult: () => {\r\n const index = pdfViewerRef.current?.search.nextResult() || -1;\r\n return index;\r\n },\r\n previousResult: () => {\r\n const index = pdfViewerRef.current?.search.previousResult() || -1;\r\n return index;\r\n },\r\n goToResult: (index: number) =>\r\n pdfViewerRef.current?.search.goToResult(index) || -1,\r\n stopSearch: () => {\r\n pdfViewerRef.current?.search.stopSearch();\r\n setSearchQuery(\"\");\r\n },\r\n getSearchState: () =>\r\n pdfViewerRef.current?.search.getSearchState() || null,\r\n getSelectedText: () =>\r\n pdfViewerRef.current?.selection.getSelectedText() || \"\",\r\n clearSelection: () => pdfViewerRef.current?.selection.clearSelection(),\r\n rotateForward: () => pdfViewerRef.current?.rotate?.rotateForward(),\r\n rotateBackward: () => pdfViewerRef.current?.rotate?.rotateBackward(),\r\n getRotation: () => pdfViewerRef.current?.rotate?.getRotation() || 0,\r\n }),\r\n []\r\n );\r\n\r\n const updatePageDisplay = () => {\r\n requestAnimationFrame(() => {\r\n const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;\r\n setCurrentPage(current);\r\n });\r\n };\r\n\r\n const updateZoomDisplay = () => {\r\n requestAnimationFrame(() => {\r\n const zoomValue = pdfViewerRef.current?.zoom.getZoom();\r\n if (typeof zoomValue === \"number\") {\r\n setZoom(Math.round(zoomValue * 100));\r\n }\r\n });\r\n };\r\n\r\n const handleSearch = async () => {\r\n if (!searchQuery.trim()) return;\r\n\r\n setIsSearching(true);\r\n const results = await pdfViewerRef.current?.search.searchText(\r\n searchQuery\r\n );\r\n setIsSearching(false);\r\n\r\n // Validate and format results\r\n if (\r\n results?.results &&\r\n Array.isArray(results.results) &&\r\n results.results.length > 0\r\n ) {\r\n const formattedResults = formatSearchResults(results.results);\r\n updateSearchState(formattedResults);\r\n } else {\r\n clearSearchResults();\r\n }\r\n };\r\n\r\n const handleSearchKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n if (e.key === \"Enter\") {\r\n handleSearch();\r\n }\r\n };\r\n\r\n const handleSidebarSearch = async (\r\n keyword: string,\r\n pageNumbers?: number[]\r\n ) => {\r\n setSearchQuery(keyword);\r\n\r\n // Handle empty search - clear results\r\n if (!keyword.trim()) {\r\n setSearchResults([]);\r\n setTotalSearchResults(0);\r\n setCurrentSearchResultIndex(0);\r\n pdfViewerRef.current?.search.stopSearch();\r\n return;\r\n }\r\n\r\n // Verify search API is available\r\n if (!pdfViewerRef.current?.search?.searchText) {\r\n console.warn(\"Search functionality not yet available\");\r\n return;\r\n }\r\n\r\n setIsSearching(true);\r\n\r\n try {\r\n // Execute PDF text search\r\n const results = await pdfViewerRef.current.search.searchText(keyword);\r\n console.log(\"Search completed:\", results);\r\n setIsSearching(false);\r\n\r\n // Validate search results\r\n const hasValidResults =\r\n results?.results &&\r\n Array.isArray(results.results) &&\r\n results.results.length > 0;\r\n\r\n if (hasValidResults) {\r\n // Format and display PDF search results\r\n const formattedResults = formatSearchResults(results.results);\r\n updateSearchState(formattedResults);\r\n navigateToFirstResult(formattedResults);\r\n } else if (pageNumbers && pageNumbers.length > 0) {\r\n // Fallback: Use OCR-provided page numbers\r\n const fallbackResults = createFallbackResults(pageNumbers, keyword);\r\n updateSearchState(fallbackResults);\r\n navigateToPage(pageNumbers[0]);\r\n } else {\r\n // No results found\r\n clearSearchResults();\r\n }\r\n } catch (error) {\r\n console.error(\"Search failed:\", error);\r\n setIsSearching(false);\r\n clearSearchResults();\r\n }\r\n };\r\n\r\n // Helper: Format raw search results into displayable format\r\n const formatSearchResults = (results: any[]) => {\r\n return results.map((result: any, index: number) => {\r\n let textContent = \"\";\r\n let contextContent = \"\";\r\n\r\n // Extract text based on result structure\r\n if (result.context && typeof result.context === \"object\") {\r\n const { before = \"\", match = \"\", after = \"\" } = result.context;\r\n textContent = match;\r\n contextContent = `${before}${match}${after}`;\r\n } else if (typeof result === \"string\") {\r\n textContent = result;\r\n contextContent = result;\r\n } else {\r\n textContent = String(result.match || result.text || \"\");\r\n contextContent = textContent;\r\n }\r\n\r\n return {\r\n pageNumber: (result.pageIndex ?? result.pageNumber ?? 0) + 1,\r\n text: textContent,\r\n context: contextContent,\r\n index: index,\r\n };\r\n });\r\n };\r\n\r\n // Helper: Create fallback results from OCR page numbers\r\n const createFallbackResults = (pageNumbers: number[], keyword: string) => {\r\n return pageNumbers.map((pageNum, index) => ({\r\n pageNumber: pageNum,\r\n text: keyword,\r\n context: `\"${keyword}\" found on this page ${pageNum}`,\r\n index: index,\r\n }));\r\n };\r\n\r\n // Helper: Update search state with results\r\n const updateSearchState = (results: any[]) => {\r\n setSearchResults(results);\r\n setTotalSearchResults(results.length);\r\n setCurrentSearchResultIndex(0);\r\n };\r\n\r\n // Helper: Clear search results\r\n const clearSearchResults = () => {\r\n setSearchResults([]);\r\n setTotalSearchResults(0);\r\n setCurrentSearchResultIndex(0);\r\n };\r\n\r\n // Helper: Navigate to first search result\r\n const navigateToFirstResult = (results: any[]) => {\r\n if (results.length > 0) {\r\n navigateToPage(results[0].pageNumber);\r\n }\r\n };\r\n\r\n // Helper: Navigate to specific page\r\n const navigateToPage = (pageNumber: number) => {\r\n requestAnimationFrame(() => {\r\n pdfViewerRef.current?.navigation.goToPage(pageNumber);\r\n setCurrentPage(pageNumber);\r\n });\r\n };\r\n\r\n const handleSearchResultClick = (\r\n pageNumber: number,\r\n resultIndex: number\r\n ) => {\r\n // Navigate to the page first\r\n pdfViewerRef.current?.navigation.goToPage(pageNumber);\r\n setCurrentSearchResultIndex(resultIndex);\r\n setCurrentPage(pageNumber);\r\n\r\n // Then go to the specific result\r\n pdfViewerRef.current?.search.goToResult(resultIndex);\r\n };\r\n\r\n const handleNextSearchResult = () => {\r\n if (currentSearchResultIndex < totalSearchResults - 1) {\r\n const nextIndex = currentSearchResultIndex + 1;\r\n setCurrentSearchResultIndex(nextIndex);\r\n\r\n pdfViewerRef.current?.search.nextResult();\r\n\r\n // Navigate to the page of the next result\r\n if (searchResults[nextIndex]) {\r\n const pageNumber = searchResults[nextIndex].pageNumber;\r\n pdfViewerRef.current?.navigation.goToPage(pageNumber);\r\n setCurrentPage(pageNumber);\r\n }\r\n }\r\n };\r\n\r\n const handlePreviousSearchResult = () => {\r\n if (currentSearchResultIndex > 0) {\r\n const prevIndex = currentSearchResultIndex - 1;\r\n setCurrentSearchResultIndex(prevIndex);\r\n\r\n pdfViewerRef.current?.search.previousResult();\r\n\r\n // Navigate to the page of the previous result\r\n if (searchResults[prevIndex]) {\r\n const pageNumber = searchResults[prevIndex].pageNumber;\r\n pdfViewerRef.current?.navigation.goToPage(pageNumber);\r\n setCurrentPage(pageNumber);\r\n }\r\n }\r\n };\r\n\r\n // Load PDF from file\r\n useEffect(() => {\r\n if (!file) {\r\n setState(\"error\");\r\n setError(\"No file provided\");\r\n return;\r\n }\r\n\r\n const loadPDF = async () => {\r\n try {\r\n setState(\"loading\");\r\n setError(null);\r\n\r\n let arrayBuffer: ArrayBuffer;\r\n\r\n if (file instanceof File) {\r\n arrayBuffer = await file.arrayBuffer();\r\n } else if (typeof file === \"string\") {\r\n // Load from URL\r\n const response = await fetch(file);\r\n if (!response.ok) {\r\n throw new Error(`Failed to load PDF: ${response.statusText}`);\r\n }\r\n arrayBuffer = await response.arrayBuffer();\r\n } else if (file instanceof ArrayBuffer) {\r\n arrayBuffer = file;\r\n } else {\r\n throw new Error(\"Unsupported file type\");\r\n }\r\n\r\n setPdfBuffer(arrayBuffer);\r\n setState(\"ready\");\r\n onLoad?.();\r\n } catch (err: any) {\r\n const errorMessage = err.message || \"Failed to load PDF\";\r\n setState(\"error\");\r\n setError(errorMessage);\r\n onError?.(err);\r\n }\r\n };\r\n\r\n loadPDF();\r\n }, [file, onLoad, onError]);\r\n\r\n // Handle password request for encrypted PDFs\r\n const handlePasswordRequest = useCallback(\r\n async (fileName?: string): Promise<string | null> => {\r\n return new Promise((resolve) => {\r\n setPasswordResolve(() => resolve);\r\n setPasswordError(\"\");\r\n setIsPasswordDialogOpen(true);\r\n });\r\n },\r\n []\r\n );\r\n\r\n const handlePasswordSubmit = useCallback(\r\n (password: string) => {\r\n if (passwordResolve) {\r\n passwordResolve(password);\r\n setPasswordResolve(null);\r\n setIsPasswordDialogOpen(false);\r\n setPasswordError(\"\");\r\n }\r\n },\r\n [passwordResolve]\r\n );\r\n\r\n const handlePasswordCancel = useCallback(() => {\r\n if (passwordResolve) {\r\n passwordResolve(null);\r\n setPasswordResolve(null);\r\n setIsPasswordDialogOpen(false);\r\n setPasswordError(\"\");\r\n }\r\n }, [passwordResolve]);\r\n\r\n if (state === \"loading\") {\r\n return (\r\n <div\r\n style={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n height: \"100%\",\r\n gap: \"16px\",\r\n }}\r\n >\r\n <div\r\n className=\"spinner\"\r\n style={{\r\n width: \"48px\",\r\n height: \"48px\",\r\n border: \"4px solid #f3f3f3\",\r\n borderTop: \"4px solid #3498db\",\r\n borderRadius: \"50%\",\r\n animation: \"spin 1s linear infinite\",\r\n }}\r\n />\r\n <p>Loading PDF...</p>\r\n <style>{`\r\n @keyframes spin {\r\n 0% { transform: rotate(0deg); }\r\n 100% { transform: rotate(360deg); }\r\n }\r\n `}</style>\r\n </div>\r\n );\r\n }\r\n\r\n if (state === \"error\" || error) {\r\n return (\r\n <div\r\n style={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n height: \"100%\",\r\n padding: \"24px\",\r\n }}\r\n >\r\n <div\r\n style={{\r\n maxWidth: \"400px\",\r\n padding: \"16px\",\r\n backgroundColor: \"#fee\",\r\n border: \"1px solid #fcc\",\r\n borderRadius: \"4px\",\r\n }}\r\n >\r\n <h3 style={{ marginTop: 0 }}>Failed to Load PDF</h3>\r\n <p>{error || \"Unknown error occurred\"}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!pdfBuffer || state !== \"ready\") {\r\n return (\r\n <div\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n height: \"100%\",\r\n }}\r\n >\r\n <p>Preparing PDF...</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div ref={containerRef} className=\"pdf-viewer-container\">\r\n <style>{toolbarStyles}</style>\r\n\r\n {/* Header - File Info */}\r\n <PDFHeader fileName={resolvedFileName} fileExtension={fileExtension} />\r\n\r\n {/* Toolbar */}\r\n <PDFToolbar\r\n currentPage={currentPage}\r\n totalPages={totalPages}\r\n zoom={zoom}\r\n isSidebarOpen={isSidebarOpen}\r\n showPageNavigation={showPageNavigation}\r\n showPageCount={showPageCount}\r\n showZoomControls={showZoomControls}\r\n showSearch={showSearch}\r\n showRotation={!toolbar.isHidden(\"rotation\")}\r\n showMetadata={!toolbar.isHidden(\"metadata\")}\r\n showProperties={!toolbar.isHidden(\"properties\")}\r\n showDownload={!toolbar.isHidden(\"download\")}\r\n showPrint={!toolbar.isHidden(\"print\")}\r\n showTags={!toolbar.isHidden(\"tags\")}\r\n disabledRotateLeft={toolbar.isDisabled(\"rotateLeft\")}\r\n disabledRotateRight={toolbar.isDisabled(\"rotateRight\")}\r\n disabledMetadata={toolbar.isDisabled(\"metadata\")}\r\n disabledTags={toolbar.isDisabled(\"tags\")}\r\n disabledProperties={toolbar.isDisabled(\"properties\")}\r\n disabledDownload={toolbar.isDisabled(\"download\")}\r\n disabledPrint={toolbar.isDisabled(\"print\")}\r\n onFirstPage={toolbarHandlers.handleFirstPage}\r\n onPreviousPage={toolbarHandlers.handlePreviousPage}\r\n onNextPage={toolbarHandlers.handleNextPage}\r\n onLastPage={toolbarHandlers.handleLastPage}\r\n onPageInput={toolbarHandlers.handlePageInput}\r\n onPageInputKeyPress={toolbarHandlers.handlePageInputKeyPress}\r\n onZoomIn={toolbarHandlers.handleZoomIn}\r\n onZoomOut={toolbarHandlers.handleZoomOut}\r\n onFitToWidth={toolbarHandlers.handleFitToWidth}\r\n onFitToPage={toolbarHandlers.handleFitToPage}\r\n onToggleSidebar={toolbarHandlers.toggleSidebar}\r\n onToggleFullScreen={toolbarHandlers.handleToggleFullScreen}\r\n onRotateLeft={toolbarHandlers.handleRotateLeft}\r\n onRotateRight={toolbarHandlers.handleRotateRight}\r\n onDownloadClick={toolbar.getHandler(\"download\", onDownloadClick)}\r\n onPrintClick={toolbar.getHandler(\"print\", onPrintClick)}\r\n onMetadataClick={toolbar.getHandler(\"metadata\", onMetadataClick)}\r\n onPropertiesClick={toolbar.getHandler(\r\n \"properties\",\r\n onPropertiesClick\r\n )}\r\n onTagsClick={toolbar.getHandler(\"tags\", onTagsClick)}\r\n />\r\n\r\n {/* Main Content Area with Sidebar */}\r\n <div className=\"pdf-viewer-main\">\r\n {/* PDF Viewer */}\r\n <div className=\"pdf-viewer-viewer-area\">\r\n <StablePDFViewer\r\n pdfBuffer={pdfBuffer}\r\n onPasswordRequest={handlePasswordRequest}\r\n pdfViewerRef={pdfViewerRef}\r\n />\r\n </div>\r\n\r\n {/* Search Sidebar */}\r\n <SearchSidebar\r\n isOpen={isSidebarOpen}\r\n onClose={handleSidebarClose}\r\n onSearch={handleSidebarSearch}\r\n onSearchResultClick={handleSearchResultClick}\r\n onNextResult={handleNextSearchResult}\r\n onPreviousResult={handlePreviousSearchResult}\r\n currentResultIndex={currentSearchResultIndex}\r\n totalResults={totalSearchResults}\r\n searchKeyword={searchQuery}\r\n searchResults={searchResults}\r\n isSearching={isSearching}\r\n />\r\n </div>\r\n\r\n {/* Password Dialog */}\r\n <PasswordDialog\r\n open={isPasswordDialogOpen}\r\n fileName={resolvedFileName}\r\n onSubmit={handlePasswordSubmit}\r\n onCancel={handlePasswordCancel}\r\n error={passwordError}\r\n />\r\n </div>\r\n );\r\n }\r\n);\r\n\r\nPDFViewerContent.displayName = \"PDFViewerContent\";\r\n\r\nexport const PDFViewer = forwardRef<PDFViewerMethods, FileViewerProps>(\r\n (props, ref) => {\r\n return (\r\n <PDFViewerContent {...props} sourceDescription=\"doc.pdf\" ref={ref} />\r\n );\r\n }\r\n);\r\n\r\nPDFViewer.displayName = \"PDFViewer\";\r\n","import React from 'react';\r\nimport { PDFViewer as HeadlessPDFViewerImport } from '@cannyminds/pdf-viewer';\r\n\r\n// Ensure we have a valid component\r\nconst HeadlessPDFViewer: any = HeadlessPDFViewerImport;\r\n\r\ninterface CannyMindsPDFViewerRef {\r\n zoom: {\r\n zoomIn: () => void;\r\n zoomOut: () => void;\r\n setZoom: (level: number) => void;\r\n resetZoom: () => void;\r\n getZoom: () => number | any;\r\n fitToWidth: () => void;\r\n fitToPage: () => void;\r\n };\r\n navigation: {\r\n goToPage: (page: number) => void;\r\n getCurrentPage: () => number;\r\n getTotalPages: () => number;\r\n nextPage: () => void;\r\n previousPage: () => void;\r\n goToFirstPage: () => void;\r\n goToLastPage: () => void;\r\n };\r\n selection: {\r\n clearSelection: () => void;\r\n getSelectedText: () => string;\r\n };\r\n search: {\r\n searchText: (keyword: string) => Promise<any>;\r\n nextResult: () => number;\r\n previousResult: () => number;\r\n goToResult: (index: number) => number;\r\n stopSearch: () => void;\r\n startSearch: () => void;\r\n getSearchState: () => any;\r\n setShowAllResults: (show: boolean) => void;\r\n };\r\n rotate?: {\r\n rotateForward: () => void;\r\n rotateBackward: () => void;\r\n setRotation: (rotation: number) => void;\r\n getRotation: () => number;\r\n };\r\n document?: {\r\n isReady: () => boolean;\r\n isLoading: () => boolean;\r\n hasPassword: () => boolean;\r\n getDocumentInfo: () => any;\r\n };\r\n scroll?: {\r\n scrollToPage: (page: number) => void;\r\n };\r\n}\r\n\r\ninterface StablePDFViewerProps {\r\n pdfBuffer: ArrayBuffer;\r\n onPasswordRequest: (fileName?: string) => Promise<string | null>;\r\n pdfViewerRef: React.RefObject<CannyMindsPDFViewerRef | null>;\r\n}\r\n\r\n// Stable PDF Viewer Component - only re-renders when PDF data changes\r\nexport const StablePDFViewer = React.memo<StablePDFViewerProps>(({ \r\n pdfBuffer, \r\n onPasswordRequest, \r\n pdfViewerRef \r\n}) => {\r\n return (\r\n <HeadlessPDFViewer\r\n ref={pdfViewerRef}\r\n pdfBuffer={pdfBuffer}\r\n onPasswordRequest={onPasswordRequest}\r\n />\r\n );\r\n});\r\n\r\nStablePDFViewer.displayName = 'StablePDFViewer';\r\n\r\nexport type { CannyMindsPDFViewerRef };","import React from \"react\";\r\nimport FirstPageIcon from \"@mui/icons-material/FirstPage\";\r\nimport LastPageIcon from \"@mui/icons-material/LastPage\";\r\nimport ChevronLeftIcon from \"@mui/icons-material/ChevronLeft\";\r\nimport ChevronRightIcon from \"@mui/icons-material/ChevronRight\";\r\nimport ZoomInIcon from \"@mui/icons-material/ZoomIn\";\r\nimport ZoomOutIcon from \"@mui/icons-material/ZoomOut\";\r\nimport FitScreenIcon from \"@mui/icons-material/FitScreen\";\r\nimport AspectRatioIcon from \"@mui/icons-material/AspectRatio\";\r\nimport SearchIcon from \"@mui/icons-material/Search\";\r\nimport FullscreenIcon from \"@mui/icons-material/Fullscreen\";\r\nimport DownloadIcon from \"@mui/icons-material/Download\";\r\nimport PrintIcon from \"@mui/icons-material/Print\";\r\nimport InfoIcon from \"@mui/icons-material/Info\";\r\nimport DescriptionIcon from \"@mui/icons-material/Description\";\r\nimport RotateLeftIcon from \"@mui/icons-material/RotateLeft\";\r\nimport RotateRightIcon from \"@mui/icons-material/RotateRight\";\r\nimport { LocalOffer } from \"@mui/icons-material\";\r\n\r\ninterface PDFToolbarProps {\r\n currentPage: number;\r\n totalPages: number;\r\n zoom: number;\r\n isSidebarOpen: boolean;\r\n showPageNavigation: boolean;\r\n showPageCount: boolean;\r\n showZoomControls: boolean;\r\n showSearch: boolean;\r\n showMetadata: boolean;\r\n showProperties: boolean;\r\n showTags: boolean;\r\n showDownload: boolean;\r\n showPrint: boolean;\r\n showRotation?: boolean;\r\n disabledRotateLeft?: boolean;\r\n disabledRotateRight?: boolean;\r\n disabledMetadata?: boolean;\r\n disabledProperties?: boolean;\r\n disabledTags?: boolean;\r\n disabledDownload?: boolean;\r\n disabledPrint?: boolean;\r\n onFirstPage: () => void;\r\n onPreviousPage: () => void;\r\n onNextPage: () => void;\r\n onLastPage: () => void;\r\n onPageInput: (e: React.ChangeEvent<HTMLInputElement>) => void;\r\n onPageInputKeyPress: (e: React.KeyboardEvent<HTMLInputElement>) => void;\r\n onZoomIn: () => void;\r\n onZoomOut: () => void;\r\n onFitToWidth: () => void;\r\n onFitToPage: () => void;\r\n onToggleSidebar: () => void;\r\n onToggleFullScreen: () => void;\r\n onRotateLeft?: () => void;\r\n onRotateRight?: () => void;\r\n onDownloadClick?: () => void;\r\n onPrintClick?: () => void;\r\n onMetadataClick?: () => void;\r\n onPropertiesClick?: () => void;\r\n onTagsClick?: () => void;\r\n}\r\n\r\nexport const PDFToolbar = React.memo<PDFToolbarProps>(\r\n ({\r\n currentPage,\r\n totalPages,\r\n zoom,\r\n isSidebarOpen,\r\n showPageNavigation,\r\n showPageCount,\r\n showZoomControls,\r\n showSearch,\r\n showMetadata,\r\n showProperties,\r\n showTags,\r\n showDownload,\r\n showPrint,\r\n showRotation,\r\n disabledRotateLeft,\r\n disabledRotateRight,\r\n disabledMetadata,\r\n disabledProperties,\r\n disabledTags,\r\n disabledDownload,\r\n disabledPrint,\r\n onFirstPage,\r\n onPreviousPage,\r\n onNextPage,\r\n onLastPage,\r\n onPageInput,\r\n onPageInputKeyPress,\r\n onZoomIn,\r\n onZoomOut,\r\n onFitToWidth,\r\n onFitToPage,\r\n onToggleSidebar,\r\n onToggleFullScreen,\r\n onRotateLeft,\r\n onRotateRight,\r\n onDownloadClick,\r\n onPrintClick,\r\n onMetadataClick,\r\n onPropertiesClick,\r\n onTagsClick,\r\n }) => {\r\n return (\r\n <div className=\"pdf-viewer-toolbar\">\r\n {showPageNavigation && (\r\n <>\r\n <div className=\"toolbar-separator\"></div>\r\n <div className=\"toolbar-section\">\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onFirstPage}\r\n disabled={currentPage <= 1}\r\n title=\"First Page\"\r\n >\r\n <FirstPageIcon fontSize=\"small\" />\r\n </button>\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onPreviousPage}\r\n disabled={currentPage <= 1}\r\n title=\"Previous Page\"\r\n >\r\n <ChevronLeftIcon fontSize=\"small\" />\r\n </button>\r\n <input\r\n type=\"number\"\r\n className=\"page-input\"\r\n value={currentPage}\r\n onChange={onPageInput}\r\n onKeyPress={onPageInputKeyPress}\r\n min={1}\r\n max={totalPages || undefined}\r\n />\r\n {showPageCount && (\r\n <span className=\"page-info\">of {totalPages || \"...\"}</span>\r\n )}\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onNextPage}\r\n disabled={currentPage >= totalPages}\r\n title=\"Next Page\"\r\n >\r\n <ChevronRightIcon fontSize=\"small\" />\r\n </button>\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onLastPage}\r\n disabled={currentPage >= totalPages}\r\n title=\"Last Page\"\r\n >\r\n <LastPageIcon fontSize=\"small\" />\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n\r\n {showZoomControls && (\r\n <>\r\n <div className=\"toolbar-separator\"></div>\r\n <div className=\"toolbar-section\">\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onZoomOut}\r\n title=\"Zoom Out\"\r\n >\r\n <ZoomOutIcon fontSize=\"small\" />\r\n </button>\r\n <span className=\"zoom-display\">{zoom}%</span>\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onZoomIn}\r\n title=\"Zoom In\"\r\n >\r\n <ZoomInIcon fontSize=\"small\" />\r\n </button>\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onFitToWidth}\r\n title=\"Fit to Width\"\r\n >\r\n <AspectRatioIcon fontSize=\"small\" />\r\n </button>\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onFitToPage}\r\n title=\"Fit to Page\"\r\n >\r\n <FitScreenIcon fontSize=\"small\" />\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n\r\n {showRotation && (\r\n <>\r\n <div className=\"toolbar-separator\"></div>\r\n <div className=\"toolbar-section\">\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onRotateLeft}\r\n disabled={disabledRotateLeft}\r\n title=\"Rotate Counterclockwise\"\r\n >\r\n <RotateLeftIcon fontSize=\"small\" />\r\n </button>\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onRotateRight}\r\n disabled={disabledRotateRight}\r\n title=\"Rotate Clockwise\"\r\n >\r\n <RotateRightIcon fontSize=\"small\" />\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n\r\n {showSearch && (\r\n <>\r\n <div className=\"toolbar-separator\"></div>\r\n <div className=\"toolbar-section\">\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onToggleSidebar}\r\n title=\"Search in PDF\"\r\n style={{\r\n backgroundColor: isSidebarOpen ? \"#e3f2fd\" : \"transparent\",\r\n color: isSidebarOpen ? \"#1976d2\" : \"inherit\",\r\n }}\r\n >\r\n <SearchIcon fontSize=\"small\" />\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n\r\n <div className=\"toolbar-separator\"></div>\r\n <div className=\"toolbar-section\">\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onToggleFullScreen}\r\n title=\"Fullscreen\"\r\n >\r\n <FullscreenIcon fontSize=\"small\" />\r\n </button>\r\n </div>\r\n\r\n {(showMetadata ||\r\n showProperties ||\r\n showDownload ||\r\n showPrint ||\r\n showTags) && (\r\n <>\r\n <div className=\"toolbar-separator\"></div>\r\n <div className=\"toolbar-section\">\r\n {showDownload && (\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onDownloadClick}\r\n disabled={disabledDownload}\r\n title=\"Download PDF\"\r\n >\r\n <DownloadIcon fontSize=\"small\" />\r\n </button>\r\n )}\r\n {showPrint && (\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onPrintClick}\r\n disabled={disabledPrint}\r\n title=\"Print PDF\"\r\n >\r\n <PrintIcon fontSize=\"small\" />\r\n </button>\r\n )}\r\n {showMetadata && (\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onMetadataClick}\r\n disabled={disabledMetadata}\r\n title=\"Document Metadata\"\r\n >\r\n <DescriptionIcon fontSize=\"small\" />\r\n </button>\r\n )}\r\n {showProperties && (\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onPropertiesClick}\r\n disabled={disabledProperties}\r\n title=\"Document Properties\"\r\n >\r\n <InfoIcon fontSize=\"small\" />\r\n </button>\r\n )}\r\n {showTags && (\r\n <button\r\n className=\"toolbar-button\"\r\n onClick={onTagsClick}\r\n disabled={disabledTags}\r\n title=\"Document Tags\"\r\n >\r\n <LocalOffer fontSize=\"small\" />\r\n </button>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n );\r\n }\r\n);\r\n\r\nPDFToolbar.displayName = \"PDFToolbar\";\r\n","import React from 'react';\nimport FileIcon from '../../FileIcon';\n\ninterface PDFHeaderProps {\n fileName: string;\n fileExtension: string;\n}\n\nexport const PDFHeader = React.memo<PDFHeaderProps>(({ fileName, fileExtension }) => {\n return (\n <div className=\"pdf-viewer-header\">\n <FileIcon ext={fileExtension} size={26} />\n <div className=\"header-file-name\" title={fileName}>\n {fileName}\n </div>\n </div>\n );\n});\n\nPDFHeader.displayName = 'PDFHeader';","import React, { useState, useLayoutEffect, useEffect, useRef } from 'react';\r\nimport {\r\n Box,\r\n Typography,\r\n TextField,\r\n IconButton,\r\n InputAdornment,\r\n Divider,\r\n CircularProgress\r\n} from '@mui/material';\r\nimport SearchIcon from '@mui/icons-material/Search';\r\nimport CloseIcon from '@mui/icons-material/Close';\r\nimport KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';\r\nimport KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';\r\nimport ClearIcon from '@mui/icons-material/Clear';\r\nimport FindInPageIcon from '@mui/icons-material/FindInPage';\r\n\r\ninterface SearchResult {\r\n pageNumber: number;\r\n text: string;\r\n context: string;\r\n index: number;\r\n}\r\n\r\ninterface SearchSidebarProps {\r\n isOpen: boolean;\r\n onClose: () => void;\r\n onSearch: (keyword: string) => void;\r\n onSearchResultClick: (pageNumber: number, resultIndex: number) => void;\r\n onNextResult: () => void;\r\n onPreviousResult: () => void;\r\n currentResultIndex: number;\r\n totalResults: number;\r\n searchKeyword: string;\r\n searchResults?: SearchResult[];\r\n isSearching?: boolean;\r\n isSyntheticResults?: boolean; // Indicates results are from OCR/document analysis\r\n}\r\n\r\nexport const SearchSidebar: React.FC<SearchSidebarProps> = ({\r\n isOpen,\r\n onClose,\r\n onSearch,\r\n onSearchResultClick,\r\n onNextResult,\r\n onPreviousResult,\r\n currentResultIndex,\r\n totalResults,\r\n searchKeyword,\r\n searchResults = [],\r\n isSearching = false,\r\n isSyntheticResults = false\r\n}) => {\r\n const [searchTerm, setSearchTerm] = useState(searchKeyword || '');\r\n const [hasSearched, setHasSearched] = useState(false);\r\n const contentRef = useRef<HTMLDivElement>(null);\r\n\r\n // Sync local search term with prop changes (for URL-based auto-search)\r\n useEffect(() => {\r\n if (searchKeyword && searchKeyword !== searchTerm) {\r\n setSearchTerm(searchKeyword);\r\n }\r\n }, [searchKeyword]);\r\n\r\n // Scrollbar hover handler\r\n useLayoutEffect(() => {\r\n const element = contentRef.current;\r\n if (!element) return;\r\n\r\n const handleMouseMove = (e: MouseEvent) => {\r\n const rect = element.getBoundingClientRect();\r\n const distanceFromRight = rect.right - e.clientX;\r\n const distanceFromBottom = rect.bottom - e.clientY;\r\n\r\n if (distanceFromRight <= 15 || distanceFromBottom <= 15) {\r\n element.classList.add('scrollbar-hover');\r\n } else {\r\n element.classList.remove('scrollbar-hover');\r\n }\r\n };\r\n\r\n const handleMouseLeave = () => element.classList.remove('scrollbar-hover');\r\n\r\n element.addEventListener('mousemove', handleMouseMove);\r\n element.addEventListener('mouseleave', handleMouseLeave);\r\n\r\n return () => {\r\n element.removeEventListener('mousemove', handleMouseMove);\r\n element.removeEventListener('mouseleave', handleMouseLeave);\r\n };\r\n }, []);\r\n\r\n // Inject scrollbar styles\r\n useLayoutEffect(() => {\r\n const style = document.createElement('style');\r\n style.id = 'search-sidebar-scrollbar';\r\n style.textContent = `\r\n @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Tamil:wght@400;600&family=Noto+Sans+Devanagari:wght@400;600&display=swap');\r\n \r\n .search-sidebar-content::-webkit-scrollbar {\r\n width: 12px;\r\n height: 12px;\r\n }\r\n .search-sidebar-content::-webkit-scrollbar-track {\r\n background-color: transparent;\r\n }\r\n .search-sidebar-content::-webkit-scrollbar-thumb {\r\n background-color: rgba(128, 128, 128, 0.3);\r\n border-radius: 8px;\r\n border: 4px solid transparent;\r\n background-clip: padding-box;\r\n transition: all 0.15s ease;\r\n }\r\n .search-sidebar-content.scrollbar-hover::-webkit-scrollbar-thumb {\r\n background-color: rgba(128, 128, 128, 0.5);\r\n border: 2px solid transparent;\r\n }\r\n .search-sidebar-content::-webkit-scrollbar-thumb:active {\r\n background-color: rgba(25, 118, 210, 0.8);\r\n border: 1px solid transparent;\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n .search-sidebar-content::-webkit-scrollbar-thumb {\r\n background-color: rgba(255, 255, 255, 0.2);\r\n }\r\n .search-sidebar-content.scrollbar-hover::-webkit-scrollbar-thumb {\r\n background-color: rgba(255, 255, 255, 0.35);\r\n }\r\n }\r\n \r\n /* Tamil font support for search results */\r\n .search-result-text {\r\n font-family: 'Noto Sans Tamil', 'Noto Sans Devanagari', Arial, sans-serif !important;\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n return () => {\r\n const el = document.getElementById('search-sidebar-scrollbar');\r\n if (el) el.remove();\r\n };\r\n }, []);\r\n\r\n useLayoutEffect(() => {\r\n setSearchTerm(searchKeyword || '');\r\n if (searchKeyword || searchResults.length > 0) {\r\n setHasSearched(true);\r\n }\r\n }, [searchKeyword, searchResults]);\r\n\r\n const handleSearchSubmit = (e?: React.FormEvent) => {\r\n if (e) e.preventDefault();\r\n\r\n if (searchTerm.trim()) {\r\n setHasSearched(true);\r\n onSearch(searchTerm.trim());\r\n }\r\n };\r\n\r\n const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const value = e.target.value;\r\n setSearchTerm(value);\r\n\r\n if (!value.trim()) {\r\n setHasSearched(false);\r\n onSearch('');\r\n }\r\n };\r\n\r\n const handleClearSearch = () => {\r\n setSearchTerm('');\r\n setHasSearched(false);\r\n onSearch('');\r\n };\r\n\r\n // Group results by page\r\n const resultsByPage = searchResults.reduce((acc, result) => {\r\n if (!acc[result.pageNumber]) {\r\n acc[result.pageNumber] = [];\r\n }\r\n acc[result.pageNumber].push(result);\r\n return acc;\r\n }, {} as Record<number, SearchResult[]>);\r\n\r\n const highlightText = (text: any, keyword: string) => {\r\n if (!keyword) return text;\r\n\r\n const textString = typeof text === 'string' ? text : String(text || '');\r\n if (!textString) return text;\r\n\r\n try {\r\n const escapedKeyword = keyword.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n const regex = new RegExp(`(${escapedKeyword})`, 'gi');\r\n const parts = textString.split(regex);\r\n\r\n return parts.map((part, index) =>\r\n regex.test(part) ? (\r\n <Box\r\n component=\"span\"\r\n key={index}\r\n sx={{\r\n color: 'primary.main',\r\n fontWeight: 600,\r\n fontSize: 'inherit'\r\n }}\r\n >\r\n {part}\r\n </Box>\r\n ) : (\r\n part\r\n )\r\n );\r\n } catch (error) {\r\n // Return plain text if highlighting fails\r\n return textString;\r\n }\r\n };\r\n\r\n if (!isOpen) return null;\r\n\r\n return (\r\n <Box\r\n sx={{\r\n display: 'flex',\r\n flexDirection: 'column',\r\n height: '100%',\r\n width: '320px',\r\n backgroundColor: 'background.paper',\r\n borderLeft: '1px solid',\r\n borderColor: 'divider',\r\n overflow: 'hidden'\r\n }}\r\n >\r\n {/* Header */}\r\n <Box sx={{ px: 3, py: 2.5, backgroundColor: 'background.default' }}>\r\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>\r\n <Typography variant=\"h6\" sx={{ fontSize: '1.125rem', fontWeight: 600, color: 'text.primary' }}>\r\n Search\r\n </Typography>\r\n <IconButton\r\n size=\"small\"\r\n onClick={onClose}\r\n sx={{\r\n color: 'text.secondary',\r\n padding: '6px'\r\n }}\r\n >\r\n <CloseIcon fontSize=\"small\" />\r\n </IconButton>\r\n </Box>\r\n\r\n {/* Search Input */}\r\n <form onSubmit={handleSearchSubmit}>\r\n <TextField\r\n fullWidth\r\n size=\"medium\"\r\n placeholder=\"Search in document...\"\r\n value={searchTerm}\r\n onChange={handleSearchChange}\r\n autoComplete=\"off\"\r\n InputProps={{\r\n startAdornment: (\r\n <InputAdornment position=\"start\">\r\n <SearchIcon sx={{ color: 'text.disabled', fontSize: 20 }} />\r\n </InputAdornment>\r\n ),\r\n endAdornment: searchTerm && (\r\n <InputAdornment position=\"end\">\r\n <IconButton\r\n size=\"small\"\r\n onClick={handleClearSearch}\r\n sx={{\r\n color: 'text.secondary',\r\n padding: '4px',\r\n '&:hover': {\r\n backgroundColor: 'action.hover'\r\n }\r\n }}\r\n >\r\n <ClearIcon sx={{ fontSize: 18 }} />\r\n </IconButton>\r\n </InputAdornment>\r\n )\r\n }}\r\n sx={{\r\n '& .MuiOutlinedInput-root': {\r\n fontSize: '0.9375rem',\r\n backgroundColor: 'background.paper',\r\n borderRadius: '8px',\r\n '& fieldset': {\r\n borderColor: 'divider'\r\n },\r\n '&.Mui-focused fieldset': {\r\n borderColor: 'primary.main',\r\n borderWidth: '2px'\r\n }\r\n },\r\n '& .MuiInputBase-input': {\r\n padding: '10px 14px'\r\n }\r\n }}\r\n />\r\n </form>\r\n\r\n {/* Results Summary and Navigation */}\r\n {totalResults > 0 && (\r\n <Box\r\n sx={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n mt: 2,\r\n pt: 2,\r\n borderTop: '1px solid',\r\n borderColor: 'divider'\r\n }}\r\n >\r\n <Typography variant=\"body2\" sx={{ color: 'text.secondary', fontSize: '0.875rem', fontWeight: 500 }}>\r\n {currentResultIndex + 1} of {totalResults} results\r\n </Typography>\r\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\r\n <IconButton\r\n size=\"small\"\r\n onClick={onPreviousResult}\r\n disabled={currentResultIndex <= 0}\r\n sx={{\r\n color: currentResultIndex <= 0 ? 'text.disabled' : 'primary.main',\r\n padding: '6px',\r\n borderRadius: '6px',\r\n border: '1px solid',\r\n borderColor: currentResultIndex <= 0 ? 'divider' : 'primary.main'\r\n }}\r\n >\r\n <KeyboardArrowUpIcon sx={{ fontSize: 20 }} />\r\n </IconButton>\r\n <IconButton\r\n size=\"small\"\r\n onClick={onNextResult}\r\n disabled={currentResultIndex >= totalResults - 1}\r\n sx={{\r\n color: currentResultIndex >= totalResults - 1 ? 'text.disabled' : 'primary.main',\r\n padding: '6px',\r\n borderRadius: '6px',\r\n border: '1px solid',\r\n borderColor: currentResultIndex >= totalResults - 1 ? 'divider' : 'primary.main'\r\n }}\r\n >\r\n <KeyboardArrowDownIcon sx={{ fontSize: 20 }} />\r\n </IconButton>\r\n </Box>\r\n </Box>\r\n )}\r\n </Box>\r\n\r\n <Divider />\r\n\r\n {/* Search Results */}\r\n <Box ref={contentRef} className=\"search-sidebar-content\" sx={{\r\n flex: 1,\r\n overflow: 'auto',\r\n backgroundColor: 'background.default'\r\n }}>\r\n {!searchTerm && !hasSearched && (\r\n <Box sx={{ p: 4, textAlign: 'center', mt: 6 }}>\r\n <Box\r\n sx={{\r\n width: 80,\r\n height: 80,\r\n borderRadius: '50%',\r\n backgroundColor: 'action.hover',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n margin: '0 auto',\r\n mb: 3\r\n }}\r\n >\r\n <SearchIcon sx={{ fontSize: 40, color: 'text.disabled' }} />\r\n </Box>\r\n <Typography variant=\"body1\" sx={{ color: 'text.primary', fontWeight: 500, mb: 1 }}>\r\n Search in Document\r\n </Typography>\r\n <Typography variant=\"body2\" sx={{ color: 'text.secondary', lineHeight: 1.6 }}>\r\n Enter keywords to find text within the PDF document\r\n </Typography>\r\n </Box>\r\n )}\r\n\r\n {searchTerm && !hasSearched && !isSearching && (\r\n <Box sx={{ p: 4, textAlign: 'center', mt: 6 }}>\r\n <Box\r\n sx={{\r\n width: 80,\r\n height: 80,\r\n borderRadius: '50%',\r\n backgroundColor: 'primary.light',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n margin: '0 auto',\r\n mb: 3,\r\n opacity: 0.2\r\n }}\r\n >\r\n <FindInPageIcon sx={{ fontSize: 40, color: 'primary.main' }} />\r\n </Box>\r\n <Typography variant=\"body1\" sx={{ color: 'text.primary', fontWeight: 500, mb: 1 }}>\r\n Ready to Search\r\n </Typography>\r\n <Typography variant=\"body2\" sx={{ color: 'text.secondary', mb: 2, lineHeight: 1.6 }}>\r\n Press Enter to find\r\n </Typography>\r\n <Typography\r\n variant=\"body2\"\r\n sx={{\r\n color: 'white',\r\n fontWeight: 600,\r\n backgroundColor: (theme) => theme.palette.mode === 'dark'\r\n ? 'rgba(144, 202, 249, 0.16)'\r\n : 'primary.light',\r\n padding: '6px 16px',\r\n borderRadius: '16px',\r\n display: 'inline-block',\r\n opacity: 0.9\r\n }}\r\n >\r\n \"{searchTerm}\"\r\n </Typography>\r\n </Box>\r\n )}\r\n\r\n {isSearching && (\r\n <Box sx={{ p: 4, textAlign: 'center', mt: 6 }}>\r\n <Box\r\n sx={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n margin: '0 auto',\r\n mb: 3\r\n }}\r\n >\r\n <CircularProgress size={60} thickness={4} />\r\n </Box>\r\n <Typography variant=\"body1\" sx={{ color: 'text.primary', fontWeight: 500, mb: 1 }}>\r\n Searching...\r\n </Typography>\r\n <Typography variant=\"body2\" sx={{ color: 'text.secondary', lineHeight: 1.6 }}>\r\n Finding matches for \"{searchTerm}\"\r\n </Typography>\r\n </Box>\r\n )}\r\n\r\n {hasSearched && totalResults === 0 && !isSearching && (\r\n <Box sx={{ p: 4, textAlign: 'center', mt: 6 }}>\r\n <Box\r\n sx={{\r\n width: 80,\r\n height: 80,\r\n borderRadius: '50%',\r\n backgroundColor: (theme) => theme.palette.mode === 'dark'\r\n ? 'rgba(255, 152, 0, 0.12)'\r\n : 'warning.light',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n margin: '0 auto',\r\n mb: 3,\r\n opacity: 0.6\r\n }}\r\n >\r\n <SearchIcon sx={{ fontSize: 40, color: 'warning.main' }} />\r\n </Box>\r\n <Typography variant=\"body1\" sx={{ color: 'text.primary', fontWeight: 500, mb: 1 }}>\r\n No Results Found\r\n </Typography>\r\n <Typography variant=\"body2\" sx={{ color: 'text.secondary', lineHeight: 1.6 }}>\r\n No matches found for <strong>\"{searchTerm}\"</strong>\r\n </Typography>\r\n </Box>\r\n )}\r\n\r\n {totalResults > 0 && (\r\n <Box sx={{ p: 2 }}>\r\n {Object.keys(resultsByPage)\r\n .sort((a, b) => parseInt(a) - parseInt(b))\r\n .map((pageNum) => {\r\n const pageNumber = parseInt(pageNum);\r\n const pageResults = resultsByPage[pageNumber];\r\n\r\n return (\r\n <Box key={pageNumber} sx={{ mb: 3 }}>\r\n {/* Page Header */}\r\n <Typography\r\n variant=\"subtitle2\"\r\n sx={{\r\n color: 'text.secondary',\r\n mb: 1.5,\r\n px: 1,\r\n fontSize: '0.8125rem',\r\n fontWeight: 600,\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.5px'\r\n }}\r\n >\r\n Page {pageNumber}\r\n </Typography>\r\n\r\n {/* Results for this page */}\r\n {pageResults.map((result: SearchResult, index: number) => (\r\n <Box\r\n key={index}\r\n onClick={() => onSearchResultClick(result.pageNumber, result.index)}\r\n sx={{\r\n p: 2,\r\n mx: 1,\r\n mb: 1.5,\r\n borderRadius: '8px',\r\n border: '2px solid',\r\n borderColor: result.index === currentResultIndex ? 'primary.main' : 'divider',\r\n backgroundColor: 'background.paper',\r\n cursor: 'pointer',\r\n transition: 'all 0.2s ease',\r\n boxShadow: (theme) => theme.palette.mode === 'dark'\r\n ? '0 1px 3px rgba(0, 0, 0, 0.3)'\r\n : '0 1px 3px rgba(0, 0, 0, 0.05)',\r\n '&:hover': {\r\n borderColor: 'primary.main',\r\n boxShadow: (theme) => theme.palette.mode === 'dark'\r\n ? '0 2px 8px rgba(255, 255, 255, 0.15)'\r\n : '0 2px 8px rgba(0, 0, 0, 0.1)',\r\n transform: 'translateY(-1px)'\r\n }\r\n }}\r\n >\r\n <Typography\r\n variant=\"body2\"\r\n className=\"search-result-text\"\r\n sx={{\r\n fontSize: '0.875rem',\r\n lineHeight: 1.6,\r\n color: result.index === currentResultIndex ? 'text.primary' : 'text.secondary'\r\n }}\r\n >\r\n {highlightText(result.context, searchTerm)}\r\n </Typography>\r\n </Box>\r\n ))}\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n};\r\n","import React, { useState, useEffect } from 'react';\r\nimport {\r\n Dialog,\r\n DialogTitle,\r\n DialogContent,\r\n DialogActions,\r\n TextField,\r\n Button,\r\n Typography,\r\n IconButton,\r\n InputAdornment,\r\n Box,\r\n Alert\r\n} from '@mui/material';\r\nimport CloseIcon from '@mui/icons-material/Close';\r\nimport LockIcon from '@mui/icons-material/Lock';\r\nimport VisibilityIcon from '@mui/icons-material/Visibility';\r\nimport VisibilityOffIcon from '@mui/icons-material/VisibilityOff';\r\n\r\ninterface PasswordDialogProps {\r\n open: boolean;\r\n fileName?: string;\r\n onSubmit: (password: string) => void;\r\n onCancel: () => void;\r\n error?: string;\r\n}\r\n\r\nexport const PasswordDialog: React.FC<PasswordDialogProps> = ({\r\n open,\r\n fileName,\r\n onSubmit,\r\n onCancel,\r\n error\r\n}) => {\r\n const [password, setPassword] = useState('');\r\n const [showPassword, setShowPassword] = useState(false);\r\n\r\n // Reset password when dialog opens/closes\r\n useEffect(() => {\r\n if (open) {\r\n setPassword('');\r\n setShowPassword(false);\r\n }\r\n }, [open]);\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (password.trim()) {\r\n onSubmit(password);\r\n }\r\n };\r\n\r\n const handleTogglePasswordVisibility = () => {\r\n setShowPassword(!showPassword);\r\n };\r\n\r\n const handleKeyPress = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && password.trim()) {\r\n handleSubmit(e as any);\r\n }\r\n };\r\n\r\n return (\r\n <Dialog\r\n open={open}\r\n onClose={onCancel}\r\n maxWidth=\"sm\"\r\n fullWidth\r\n PaperProps={{\r\n sx: {\r\n borderRadius: 2\r\n }\r\n }}\r\n >\r\n <DialogTitle sx={{ pb: 1 }}>\r\n <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\r\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>\r\n <Box\r\n sx={{\r\n width: 40,\r\n height: 40,\r\n borderRadius: '50%',\r\n backgroundColor: 'primary.light',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n opacity: 0.9\r\n }}\r\n >\r\n <LockIcon sx={{ color: 'white', fontSize: 20 }} />\r\n </Box>\r\n <Typography variant=\"h6\" component=\"div\" sx={{ fontWeight: 600 }}>\r\n Password Protected\r\n </Typography>\r\n </Box>\r\n <IconButton\r\n size=\"small\"\r\n onClick={onCancel}\r\n sx={{ color: 'text.secondary' }}\r\n aria-label=\"Close dialog\"\r\n >\r\n <CloseIcon fontSize=\"small\" />\r\n </IconButton>\r\n </Box>\r\n </DialogTitle>\r\n\r\n <DialogContent sx={{ pt: 2 }}>\r\n <Typography variant=\"body2\" sx={{ color: 'text.secondary', mb: 3 }}>\r\n This PDF is password protected. Please enter the password to view{' '}\r\n {fileName && <strong>\"{fileName}\"</strong>}\r\n </Typography>\r\n\r\n {error && (\r\n <Alert severity=\"error\" sx={{ mb: 2 }}>\r\n {error}\r\n </Alert>\r\n )}\r\n\r\n <form onSubmit={handleSubmit}>\r\n <TextField\r\n fullWidth\r\n autoFocus\r\n type={showPassword ? 'text' : 'password'}\r\n label=\"Password\"\r\n placeholder=\"Enter password\"\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n onKeyPress={handleKeyPress}\r\n error={Boolean(error)}\r\n InputProps={{\r\n endAdornment: (\r\n <InputAdornment position=\"end\">\r\n <IconButton\r\n onClick={handleTogglePasswordVisibility}\r\n edge=\"end\"\r\n size=\"small\"\r\n aria-label={showPassword ? 'Hide password' : 'Show password'}\r\n >\r\n {showPassword ? <VisibilityOffIcon /> : <VisibilityIcon />}\r\n </IconButton>\r\n </InputAdornment>\r\n )\r\n }}\r\n sx={{\r\n '& .MuiOutlinedInput-root': {\r\n borderRadius: 2\r\n }\r\n }}\r\n />\r\n </form>\r\n </DialogContent>\r\n\r\n <DialogActions sx={{ px: 3, pb: 3, pt: 2 }}>\r\n <Button\r\n onClick={onCancel}\r\n variant=\"outlined\"\r\n sx={{\r\n borderRadius: 2,\r\n textTransform: 'none',\r\n px: 3\r\n }}\r\n >\r\n Cancel\r\n </Button>\r\n <Button\r\n onClick={handleSubmit}\r\n variant=\"contained\"\r\n disabled={!password.trim()}\r\n sx={{\r\n borderRadius: 2,\r\n textTransform: 'none',\r\n px: 3,\r\n boxShadow: 2\r\n }}\r\n >\r\n Unlock PDF\r\n </Button>\r\n </DialogActions>\r\n </Dialog>\r\n );\r\n};"],"mappings":"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","names":["useEffect","useRef","useState","React","jsx","React","jsx","jsxs","React","SearchIcon","jsx","jsxs","useState","useEffect","TextField","Typography","IconButton","InputAdornment","Box","CloseIcon","jsx","jsxs","jsx","jsxs","useState","useRef","useEffect","error","zoom","fileName"]}
@@ -0,0 +1,266 @@
1
+ "use client";
2
+ import {
3
+ getFileExtension
4
+ } from "./chunk-M57PSU4O.mjs";
5
+ import {
6
+ FileIcon_default,
7
+ mergeToolbarConfig
8
+ } from "./chunk-WR5SJ3LM.mjs";
9
+
10
+ // src/components/viewers/AudioViewer.tsx
11
+ import {
12
+ useEffect,
13
+ useMemo,
14
+ useRef,
15
+ useState
16
+ } from "react";
17
+ import {
18
+ Box,
19
+ Card,
20
+ CardContent,
21
+ CardHeader,
22
+ LinearProgress,
23
+ Typography,
24
+ IconButton,
25
+ Tooltip,
26
+ Stack
27
+ } from "@mui/material";
28
+ import DownloadIcon from "@mui/icons-material/Download";
29
+ import PrintIcon from "@mui/icons-material/Print";
30
+ import FullscreenIcon from "@mui/icons-material/Fullscreen";
31
+ import InfoIcon from "@mui/icons-material/Info";
32
+ import DescriptionIcon from "@mui/icons-material/Description";
33
+ import { jsx, jsxs } from "react/jsx-runtime";
34
+ var AudioViewer = ({
35
+ file,
36
+ url,
37
+ fileName,
38
+ className = "",
39
+ style = {},
40
+ width = "100%",
41
+ height = "100%",
42
+ onLoad,
43
+ onError,
44
+ onDownloadClick,
45
+ onPrintClick,
46
+ onMetadataClick,
47
+ onPropertiesClick,
48
+ showDownload = true,
49
+ showPrint = false,
50
+ showMetadata = false,
51
+ showProperties = false,
52
+ showTags = false,
53
+ // Extract props that shouldn't be passed to DOM elements
54
+ mimeType,
55
+ fileSize,
56
+ showPageCount,
57
+ showPageNavigation,
58
+ showZoomControls,
59
+ showSearch,
60
+ customRegistry,
61
+ initialSearchText,
62
+ initialSearchPages,
63
+ autoOpenSearch,
64
+ autoExecuteSearch,
65
+ onSearchComplete,
66
+ toolbarActions,
67
+ ...props
68
+ }) => {
69
+ const audioRef = useRef(null);
70
+ const containerRef = useRef(null);
71
+ const [objectUrl, setObjectUrl] = useState(null);
72
+ const [isLoading, setIsLoading] = useState(false);
73
+ const [error, setError] = useState(null);
74
+ const [isFullScreen, setIsFullScreen] = useState(false);
75
+ useEffect(() => {
76
+ let urlValue = null;
77
+ if (file) {
78
+ setIsLoading(true);
79
+ urlValue = URL.createObjectURL(file);
80
+ } else if (url) {
81
+ urlValue = url;
82
+ }
83
+ setObjectUrl(urlValue);
84
+ setError(null);
85
+ return () => {
86
+ if (urlValue && file) {
87
+ URL.revokeObjectURL(urlValue);
88
+ }
89
+ };
90
+ }, [file, url]);
91
+ useEffect(() => {
92
+ if (!audioRef.current) {
93
+ return;
94
+ }
95
+ const handleLoadedMetadata = () => {
96
+ setIsLoading(false);
97
+ onLoad?.();
98
+ };
99
+ const handleError = () => {
100
+ const message = "Failed to load audio resource";
101
+ setIsLoading(false);
102
+ setError(message);
103
+ onError?.(new Error(message));
104
+ };
105
+ const element = audioRef.current;
106
+ element.addEventListener("loadedmetadata", handleLoadedMetadata);
107
+ element.addEventListener("error", handleError);
108
+ return () => {
109
+ element.removeEventListener("loadedmetadata", handleLoadedMetadata);
110
+ element.removeEventListener("error", handleError);
111
+ };
112
+ }, [onLoad, onError, objectUrl]);
113
+ const resolvedFileName = useMemo(
114
+ () => fileName || file?.name || (url ? url.split("/").pop() : "audio"),
115
+ [fileName, file, url]
116
+ );
117
+ const fileExtension = useMemo(
118
+ () => getFileExtension(resolvedFileName || ""),
119
+ [resolvedFileName]
120
+ );
121
+ const handleToggleFullScreen = () => {
122
+ if (!isFullScreen && containerRef.current?.requestFullscreen) {
123
+ containerRef.current.requestFullscreen();
124
+ setIsFullScreen(true);
125
+ } else if (isFullScreen && document.exitFullscreen) {
126
+ document.exitFullscreen();
127
+ setIsFullScreen(false);
128
+ }
129
+ };
130
+ const toolbar = mergeToolbarConfig({
131
+ showDownload,
132
+ showPrint,
133
+ showMetadata,
134
+ showTags,
135
+ showProperties,
136
+ onDownloadClick,
137
+ onPrintClick,
138
+ onMetadataClick,
139
+ onPropertiesClick,
140
+ toolbarActions
141
+ });
142
+ return /* @__PURE__ */ jsx(
143
+ Box,
144
+ {
145
+ ref: containerRef,
146
+ className: `audio-viewer ${className}`,
147
+ sx: { width, height, ...style },
148
+ ...props,
149
+ children: /* @__PURE__ */ jsxs(
150
+ Card,
151
+ {
152
+ sx: { height: "100%", display: "flex", flexDirection: "column" },
153
+ elevation: 1,
154
+ children: [
155
+ /* @__PURE__ */ jsx(
156
+ CardHeader,
157
+ {
158
+ avatar: /* @__PURE__ */ jsx(FileIcon_default, { ext: fileExtension, size: 32 }),
159
+ title: /* @__PURE__ */ jsx(Typography, { variant: "subtitle1", fontWeight: 500, children: resolvedFileName }),
160
+ action: /* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 1, children: [
161
+ !toolbar.isHidden("download") && /* @__PURE__ */ jsx(Tooltip, { title: toolbar.getLabel("download") || "Download", children: /* @__PURE__ */ jsx(
162
+ IconButton,
163
+ {
164
+ size: "small",
165
+ onClick: toolbar.getHandler("download", onDownloadClick),
166
+ disabled: toolbar.isDisabled("download"),
167
+ "aria-label": "Download audio",
168
+ children: toolbar.getIcon("download") || /* @__PURE__ */ jsx(DownloadIcon, {})
169
+ }
170
+ ) }),
171
+ !toolbar.isHidden("print") && /* @__PURE__ */ jsx(Tooltip, { title: toolbar.getLabel("print") || "Print", children: /* @__PURE__ */ jsx(
172
+ IconButton,
173
+ {
174
+ size: "small",
175
+ onClick: toolbar.getHandler("print", onPrintClick),
176
+ disabled: toolbar.isDisabled("print"),
177
+ "aria-label": "Print audio",
178
+ children: toolbar.getIcon("print") || /* @__PURE__ */ jsx(PrintIcon, {})
179
+ }
180
+ ) }),
181
+ !toolbar.isHidden("fullscreen") && /* @__PURE__ */ jsx(Tooltip, { title: toolbar.getLabel("fullscreen") || "Fullscreen", children: /* @__PURE__ */ jsx(
182
+ IconButton,
183
+ {
184
+ size: "small",
185
+ onClick: toolbar.getHandler(
186
+ "fullscreen",
187
+ handleToggleFullScreen
188
+ ),
189
+ disabled: toolbar.isDisabled("fullscreen"),
190
+ "aria-label": "Toggle fullscreen",
191
+ children: toolbar.getIcon("fullscreen") || /* @__PURE__ */ jsx(FullscreenIcon, {})
192
+ }
193
+ ) }),
194
+ !toolbar.isHidden("metadata") && /* @__PURE__ */ jsx(
195
+ Tooltip,
196
+ {
197
+ title: toolbar.getLabel("metadata") || "Document Metadata",
198
+ children: /* @__PURE__ */ jsx(
199
+ IconButton,
200
+ {
201
+ size: "small",
202
+ onClick: toolbar.getHandler("metadata", onMetadataClick),
203
+ disabled: toolbar.isDisabled("metadata"),
204
+ "aria-label": "View document metadata",
205
+ children: toolbar.getIcon("metadata") || /* @__PURE__ */ jsx(DescriptionIcon, {})
206
+ }
207
+ )
208
+ }
209
+ ),
210
+ !toolbar.isHidden("properties") && /* @__PURE__ */ jsx(
211
+ Tooltip,
212
+ {
213
+ title: toolbar.getLabel("properties") || "Document Properties",
214
+ children: /* @__PURE__ */ jsx(
215
+ IconButton,
216
+ {
217
+ size: "small",
218
+ onClick: toolbar.getHandler(
219
+ "properties",
220
+ onPropertiesClick
221
+ ),
222
+ disabled: toolbar.isDisabled("properties"),
223
+ "aria-label": "View document properties",
224
+ children: toolbar.getIcon("properties") || /* @__PURE__ */ jsx(InfoIcon, {})
225
+ }
226
+ )
227
+ }
228
+ )
229
+ ] }),
230
+ sx: { pb: 1.5 }
231
+ }
232
+ ),
233
+ isLoading && /* @__PURE__ */ jsx(LinearProgress, { sx: { mx: 3, mb: 2 } }),
234
+ error && /* @__PURE__ */ jsx(Typography, { color: "error", variant: "body2", sx: { px: 3, pb: 1 }, children: error }),
235
+ /* @__PURE__ */ jsx(
236
+ CardContent,
237
+ {
238
+ sx: {
239
+ flexGrow: 1,
240
+ display: "flex",
241
+ alignItems: "center",
242
+ justifyContent: "center"
243
+ },
244
+ children: objectUrl ? /* @__PURE__ */ jsx(
245
+ "audio",
246
+ {
247
+ ref: audioRef,
248
+ controls: true,
249
+ controlsList: "nodownload",
250
+ style: { width: "100%" },
251
+ src: objectUrl
252
+ }
253
+ ) : /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: "No audio source provided." })
254
+ }
255
+ )
256
+ ]
257
+ }
258
+ )
259
+ }
260
+ );
261
+ };
262
+
263
+ export {
264
+ AudioViewer
265
+ };
266
+ //# sourceMappingURL=chunk-VBJVOB45.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/viewers/AudioViewer.tsx"],"sourcesContent":["import React, {\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useState,\r\n} from \"react\";\r\nimport {\r\n Box,\r\n Card,\r\n CardContent,\r\n CardHeader,\r\n LinearProgress,\r\n Typography,\r\n IconButton,\r\n Tooltip,\r\n Stack,\r\n} from \"@mui/material\";\r\nimport DownloadIcon from \"@mui/icons-material/Download\";\r\nimport PrintIcon from \"@mui/icons-material/Print\";\r\nimport FullscreenIcon from \"@mui/icons-material/Fullscreen\";\r\nimport InfoIcon from \"@mui/icons-material/Info\";\r\nimport DescriptionIcon from \"@mui/icons-material/Description\";\r\nimport { FileViewerProps } from \"../../types\";\r\nimport { getFileExtension } from \"../../utils/fileUtils\";\r\nimport { mergeToolbarConfig } from \"../../utils/toolbarUtils\";\r\nimport FileIcon from \"../FileIcon\";\r\n\r\nexport const AudioViewer: React.FC<FileViewerProps> = ({\r\n file,\r\n url,\r\n fileName,\r\n className = \"\",\r\n style = {},\r\n width = \"100%\",\r\n height = \"100%\",\r\n onLoad,\r\n onError,\r\n onDownloadClick,\r\n onPrintClick,\r\n onMetadataClick,\r\n onPropertiesClick,\r\n showDownload = true,\r\n showPrint = false,\r\n showMetadata = false,\r\n showProperties = false,\r\n showTags = false,\r\n // Extract props that shouldn't be passed to DOM elements\r\n mimeType,\r\n fileSize,\r\n showPageCount,\r\n showPageNavigation,\r\n showZoomControls,\r\n showSearch,\r\n customRegistry,\r\n initialSearchText,\r\n initialSearchPages,\r\n autoOpenSearch,\r\n autoExecuteSearch,\r\n onSearchComplete,\r\n toolbarActions,\r\n ...props\r\n}) => {\r\n const audioRef = useRef<HTMLAudioElement | null>(null);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const [objectUrl, setObjectUrl] = useState<string | null>(null);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [isFullScreen, setIsFullScreen] = useState(false);\r\n\r\n useEffect(() => {\r\n let urlValue: string | null = null;\r\n\r\n if (file) {\r\n setIsLoading(true);\r\n urlValue = URL.createObjectURL(file);\r\n } else if (url) {\r\n urlValue = url;\r\n }\r\n\r\n setObjectUrl(urlValue);\r\n setError(null);\r\n\r\n return () => {\r\n if (urlValue && file) {\r\n URL.revokeObjectURL(urlValue);\r\n }\r\n };\r\n }, [file, url]);\r\n\r\n useEffect(() => {\r\n if (!audioRef.current) {\r\n return;\r\n }\r\n\r\n const handleLoadedMetadata = () => {\r\n setIsLoading(false);\r\n onLoad?.();\r\n };\r\n\r\n const handleError = () => {\r\n const message = \"Failed to load audio resource\";\r\n setIsLoading(false);\r\n setError(message);\r\n onError?.(new Error(message));\r\n };\r\n\r\n const element = audioRef.current;\r\n element.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\r\n element.addEventListener(\"error\", handleError);\r\n\r\n return () => {\r\n element.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\r\n element.removeEventListener(\"error\", handleError);\r\n };\r\n }, [onLoad, onError, objectUrl]);\r\n\r\n const resolvedFileName = useMemo(\r\n () => fileName || file?.name || (url ? url.split(\"/\").pop() : \"audio\"),\r\n [fileName, file, url]\r\n );\r\n\r\n const fileExtension = useMemo(\r\n () => getFileExtension(resolvedFileName || \"\"),\r\n [resolvedFileName]\r\n );\r\n\r\n const handleToggleFullScreen = () => {\r\n if (!isFullScreen && containerRef.current?.requestFullscreen) {\r\n containerRef.current.requestFullscreen();\r\n setIsFullScreen(true);\r\n } else if (isFullScreen && document.exitFullscreen) {\r\n document.exitFullscreen();\r\n setIsFullScreen(false);\r\n }\r\n };\r\n\r\n const toolbar = mergeToolbarConfig({\r\n showDownload,\r\n showPrint,\r\n showMetadata,\r\n showTags,\r\n showProperties,\r\n onDownloadClick,\r\n onPrintClick,\r\n onMetadataClick,\r\n onPropertiesClick,\r\n toolbarActions,\r\n });\r\n\r\n return (\r\n <Box\r\n ref={containerRef}\r\n className={`audio-viewer ${className}`}\r\n sx={{ width, height, ...style }}\r\n {...props}\r\n >\r\n <Card\r\n sx={{ height: \"100%\", display: \"flex\", flexDirection: \"column\" }}\r\n elevation={1}\r\n >\r\n <CardHeader\r\n avatar={<FileIcon ext={fileExtension} size={32} />}\r\n title={\r\n <Typography variant=\"subtitle1\" fontWeight={500}>\r\n {resolvedFileName}\r\n </Typography>\r\n }\r\n action={\r\n <Stack direction=\"row\" spacing={1}>\r\n {!toolbar.isHidden(\"download\") && (\r\n <Tooltip title={toolbar.getLabel(\"download\") || \"Download\"}>\r\n <IconButton\r\n size=\"small\"\r\n onClick={toolbar.getHandler(\"download\", onDownloadClick)}\r\n disabled={toolbar.isDisabled(\"download\")}\r\n aria-label=\"Download audio\"\r\n >\r\n {toolbar.getIcon(\"download\") || <DownloadIcon />}\r\n </IconButton>\r\n </Tooltip>\r\n )}\r\n {!toolbar.isHidden(\"print\") && (\r\n <Tooltip title={toolbar.getLabel(\"print\") || \"Print\"}>\r\n <IconButton\r\n size=\"small\"\r\n onClick={toolbar.getHandler(\"print\", onPrintClick)}\r\n disabled={toolbar.isDisabled(\"print\")}\r\n aria-label=\"Print audio\"\r\n >\r\n {toolbar.getIcon(\"print\") || <PrintIcon />}\r\n </IconButton>\r\n </Tooltip>\r\n )}\r\n {!toolbar.isHidden(\"fullscreen\") && (\r\n <Tooltip title={toolbar.getLabel(\"fullscreen\") || \"Fullscreen\"}>\r\n <IconButton\r\n size=\"small\"\r\n onClick={toolbar.getHandler(\r\n \"fullscreen\",\r\n handleToggleFullScreen\r\n )}\r\n disabled={toolbar.isDisabled(\"fullscreen\")}\r\n aria-label=\"Toggle fullscreen\"\r\n >\r\n {toolbar.getIcon(\"fullscreen\") || <FullscreenIcon />}\r\n </IconButton>\r\n </Tooltip>\r\n )}\r\n {!toolbar.isHidden(\"metadata\") && (\r\n <Tooltip\r\n title={toolbar.getLabel(\"metadata\") || \"Document Metadata\"}\r\n >\r\n <IconButton\r\n size=\"small\"\r\n onClick={toolbar.getHandler(\"metadata\", onMetadataClick)}\r\n disabled={toolbar.isDisabled(\"metadata\")}\r\n aria-label=\"View document metadata\"\r\n >\r\n {toolbar.getIcon(\"metadata\") || <DescriptionIcon />}\r\n </IconButton>\r\n </Tooltip>\r\n )}\r\n {!toolbar.isHidden(\"properties\") && (\r\n <Tooltip\r\n title={\r\n toolbar.getLabel(\"properties\") || \"Document Properties\"\r\n }\r\n >\r\n <IconButton\r\n size=\"small\"\r\n onClick={toolbar.getHandler(\r\n \"properties\",\r\n onPropertiesClick\r\n )}\r\n disabled={toolbar.isDisabled(\"properties\")}\r\n aria-label=\"View document properties\"\r\n >\r\n {toolbar.getIcon(\"properties\") || <InfoIcon />}\r\n </IconButton>\r\n </Tooltip>\r\n )}\r\n </Stack>\r\n }\r\n sx={{ pb: 1.5 }}\r\n />\r\n {isLoading && <LinearProgress sx={{ mx: 3, mb: 2 }} />}\r\n {error && (\r\n <Typography color=\"error\" variant=\"body2\" sx={{ px: 3, pb: 1 }}>\r\n {error}\r\n </Typography>\r\n )}\r\n <CardContent\r\n sx={{\r\n flexGrow: 1,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n }}\r\n >\r\n {objectUrl ? (\r\n <audio\r\n ref={audioRef}\r\n controls\r\n controlsList=\"nodownload\"\r\n style={{ width: \"100%\" }}\r\n src={objectUrl}\r\n />\r\n ) : (\r\n <Typography variant=\"body2\" color=\"text.secondary\">\r\n No audio source provided.\r\n </Typography>\r\n )}\r\n </CardContent>\r\n </Card>\r\n </Box>\r\n );\r\n};\r\n"],"mappings":"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","names":[]}
@@ -9,6 +9,7 @@ function mergeToolbarConfig(props) {
9
9
  search: props.showSearch,
10
10
  metadata: props.showMetadata,
11
11
  properties: props.showProperties,
12
+ tags: props.showTags,
12
13
  pageNavigation: props.showPageNavigation,
13
14
  zoomControls: props.showZoomControls,
14
15
  pageCount: props.showPageCount,
@@ -283,4 +284,4 @@ export {
283
284
  mergeToolbarConfig,
284
285
  FileIcon_default
285
286
  };
286
- //# sourceMappingURL=chunk-DFBVN4MO.mjs.map
287
+ //# sourceMappingURL=chunk-WR5SJ3LM.mjs.map