@page-speed/lightbox 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -18065,7 +18065,7 @@ var require_pdf = __commonJS({
18065
18065
  }
18066
18066
  });
18067
18067
 
18068
- // node_modules/.pnpm/@page-speed+pdf-viewer@0.1.4_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js
18068
+ // node_modules/.pnpm/@page-speed+pdf-viewer@0.1.6_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js
18069
18069
  var dist_exports = {};
18070
18070
  __export(dist_exports, {
18071
18071
  PDFCanvas: () => PDFCanvas,
@@ -18075,11 +18075,14 @@ __export(dist_exports, {
18075
18075
  calculateScaleForPageFit: () => calculateScaleForPageFit,
18076
18076
  createProgressiveFetchHandler: () => createProgressiveFetchHandler,
18077
18077
  downloadPDF: () => downloadPDF,
18078
+ extractPDFFilename: () => extractPDFFilename,
18078
18079
  extractPageText: () => extractPageText,
18079
18080
  formatFileSize: () => formatFileSize,
18080
18081
  getOptimalRangeHeader: () => getOptimalRangeHeader,
18082
+ injectPDFViewerStyles: () => injectPDFViewerStyles,
18081
18083
  isLinearizedPDF: () => isLinearizedPDF,
18082
18084
  linearizedPDFConfig: () => linearizedPDFConfig,
18085
+ pdfViewerStyles: () => pdfViewerStyles,
18083
18086
  usePDFDocument: () => usePDFDocument,
18084
18087
  usePageRenderer: () => usePageRenderer,
18085
18088
  usePageState: () => usePageState,
@@ -18320,6 +18323,20 @@ function useSearch(pdfDoc) {
18320
18323
  prevResult
18321
18324
  };
18322
18325
  }
18326
+ function injectPDFViewerStyles() {
18327
+ if (typeof document === "undefined") return;
18328
+ if (stylesInjected) return;
18329
+ const styleId = "page-speed-pdf-viewer-styles";
18330
+ if (document.getElementById(styleId)) {
18331
+ stylesInjected = true;
18332
+ return;
18333
+ }
18334
+ const styleElement = document.createElement("style");
18335
+ styleElement.id = styleId;
18336
+ styleElement.textContent = PDF_VIEWER_STYLES;
18337
+ document.head.appendChild(styleElement);
18338
+ stylesInjected = true;
18339
+ }
18323
18340
  function PDFCanvas({
18324
18341
  pdfDoc,
18325
18342
  pageNumber,
@@ -18343,7 +18360,68 @@ function PDFCanvas({
18343
18360
  render();
18344
18361
  }
18345
18362
  }, [pdfDoc, pageNumber, scale, onRender]);
18346
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: containerRef, className: PDFViewer_default.canvas });
18363
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: containerRef, className: pdfViewerStyles.canvas });
18364
+ }
18365
+ async function isLinearizedPDF(url) {
18366
+ try {
18367
+ const response = await fetch(url, { headers: { Range: "bytes=0-1024" } });
18368
+ const buffer = await response.arrayBuffer();
18369
+ const view = new Uint8Array(buffer);
18370
+ const text = new TextDecoder().decode(view);
18371
+ return text.includes("Linearized");
18372
+ } catch {
18373
+ return false;
18374
+ }
18375
+ }
18376
+ function extractPDFFilename(url, fallbackName) {
18377
+ try {
18378
+ const urlObj = new URL(url, window.location.origin);
18379
+ const pathname = urlObj.pathname;
18380
+ const segments = pathname.split("/").filter(Boolean);
18381
+ const lastSegment = segments[segments.length - 1] || "";
18382
+ if (lastSegment && lastSegment.includes(".")) {
18383
+ if (lastSegment.toLowerCase().endsWith(".pdf")) {
18384
+ return lastSegment;
18385
+ }
18386
+ const nameWithoutExt = lastSegment.substring(0, lastSegment.lastIndexOf("."));
18387
+ return `${nameWithoutExt}.pdf`;
18388
+ }
18389
+ if (lastSegment) {
18390
+ return `${lastSegment}.pdf`;
18391
+ }
18392
+ } catch {
18393
+ }
18394
+ const name = fallbackName || "document";
18395
+ return name.toLowerCase().endsWith(".pdf") ? name : `${name}.pdf`;
18396
+ }
18397
+ function downloadPDF(url, filename) {
18398
+ const link = document.createElement("a");
18399
+ link.href = url;
18400
+ link.download = filename || extractPDFFilename(url);
18401
+ document.body.appendChild(link);
18402
+ link.click();
18403
+ document.body.removeChild(link);
18404
+ }
18405
+ function calculateScaleForPageFit(pageWidth, pageHeight, containerWidth, containerHeight) {
18406
+ const widthRatio = containerWidth / pageWidth;
18407
+ const heightRatio = containerHeight / pageHeight;
18408
+ return Math.min(widthRatio, heightRatio);
18409
+ }
18410
+ function formatFileSize(bytes) {
18411
+ if (bytes === 0) return "0 Bytes";
18412
+ const k = 1024;
18413
+ const sizes = ["Bytes", "KB", "MB", "GB"];
18414
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
18415
+ return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
18416
+ }
18417
+ async function extractPageText(pdfDoc, pageNumber) {
18418
+ try {
18419
+ const page = await pdfDoc.getPage(pageNumber);
18420
+ const textContent = await page.getTextContent();
18421
+ return textContent.items.filter((item) => "str" in item).map((item) => item.str).join(" ");
18422
+ } catch {
18423
+ return "";
18424
+ }
18347
18425
  }
18348
18426
  function PDFControls({
18349
18427
  pageState,
@@ -18356,7 +18434,7 @@ function PDFControls({
18356
18434
  url
18357
18435
  }) {
18358
18436
  if (!pdfDocument) return null;
18359
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: PDFViewer_default.controls, children: [
18437
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: pdfViewerStyles.controls, children: [
18360
18438
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
18361
18439
  "button",
18362
18440
  {
@@ -18374,10 +18452,10 @@ function PDFControls({
18374
18452
  max: pdfDocument.numPages,
18375
18453
  value: pageState.currentPage,
18376
18454
  onChange: (e) => pageState.goToPage(parseInt(e.target.value, 10) || 1),
18377
- className: PDFViewer_default.pageInput
18455
+ className: pdfViewerStyles.pageInput
18378
18456
  }
18379
18457
  ),
18380
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: PDFViewer_default.pageTotal, children: [
18458
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: pdfViewerStyles.pageTotal, children: [
18381
18459
  "of ",
18382
18460
  pdfDocument.numPages
18383
18461
  ] }),
@@ -18399,7 +18477,7 @@ function PDFControls({
18399
18477
  children: "-"
18400
18478
  }
18401
18479
  ),
18402
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: PDFViewer_default.zoomLevel, children: [
18480
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: pdfViewerStyles.zoomLevel, children: [
18403
18481
  Math.round(zoom.zoomLevel * 100),
18404
18482
  "%"
18405
18483
  ] }),
@@ -18419,14 +18497,22 @@ function PDFControls({
18419
18497
  placeholder: "Search...",
18420
18498
  value: search.query,
18421
18499
  onChange: (e) => search.search(e.target.value),
18422
- className: PDFViewer_default.searchInput
18500
+ className: pdfViewerStyles.searchInput
18423
18501
  }
18424
18502
  ),
18425
- search.results.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: PDFViewer_default.searchResults, children: [
18503
+ search.results.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: pdfViewerStyles.searchResults, children: [
18426
18504
  search.results.length,
18427
18505
  " results"
18428
18506
  ] }),
18429
- enableDownload && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("a", { href: url, download: true, className: PDFViewer_default.button, title: "Download", children: "Download" }),
18507
+ enableDownload && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
18508
+ "button",
18509
+ {
18510
+ onClick: () => downloadPDF(url),
18511
+ className: pdfViewerStyles.button,
18512
+ title: "Download",
18513
+ children: "Download"
18514
+ }
18515
+ ),
18430
18516
  enablePrint && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: () => window.print(), title: "Print", children: "Print" }),
18431
18517
  enableFullscreen && typeof document !== "undefined" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
18432
18518
  "button",
@@ -18480,10 +18566,10 @@ function PDFThumbnails({
18480
18566
  };
18481
18567
  generateThumbnails();
18482
18568
  }, [pdfDoc, numPages]);
18483
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: PDFViewer_default.thumbnails, children: thumbnails.map((thumb, idx) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
18569
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: pdfViewerStyles.thumbnails, children: thumbnails.map((thumb, idx) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
18484
18570
  "div",
18485
18571
  {
18486
- className: `${PDFViewer_default.thumbnail} ${idx + 1 === currentPage ? PDFViewer_default.active : ""}`,
18572
+ className: `${pdfViewerStyles.thumbnail} ${idx + 1 === currentPage ? pdfViewerStyles.active : ""}`,
18487
18573
  onClick: () => onSelectPage(idx + 1),
18488
18574
  children: [
18489
18575
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
@@ -18501,7 +18587,7 @@ function PDFThumbnails({
18501
18587
  }
18502
18588
  }
18503
18589
  ),
18504
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: PDFViewer_default.pageNumber, children: idx + 1 })
18590
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: pdfViewerStyles.pageNumber, children: idx + 1 })
18505
18591
  ]
18506
18592
  },
18507
18593
  idx
@@ -18531,6 +18617,9 @@ function PDFViewer({
18531
18617
  initialZoom = "auto",
18532
18618
  withCredentials = false
18533
18619
  } = config;
18620
+ (0, import_react8.useEffect)(() => {
18621
+ injectPDFViewerStyles();
18622
+ }, []);
18534
18623
  const { document: document2, pdfDoc, loading, error } = usePDFDocument(url, onError, withCredentials);
18535
18624
  const pageState = usePageState({
18536
18625
  totalPages: document2?.numPages || 0,
@@ -18553,18 +18642,18 @@ function PDFViewer({
18553
18642
  }
18554
18643
  }, [search.results, onSearchResults]);
18555
18644
  if (error) {
18556
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: PDFViewer_default.error, style: { height, width }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { children: [
18645
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: pdfViewerStyles.error, style: { height, width }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { children: [
18557
18646
  "Failed to load PDF: ",
18558
18647
  error.message
18559
18648
  ] }) });
18560
18649
  }
18561
18650
  if (loading) {
18562
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: PDFViewer_default.loading, style: { height, width }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "Loading PDF..." }) });
18651
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: pdfViewerStyles.loading, style: { height, width }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "Loading PDF..." }) });
18563
18652
  }
18564
18653
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
18565
18654
  "div",
18566
18655
  {
18567
- className: `${PDFViewer_default.viewer} ${className || ""}`,
18656
+ className: `${pdfViewerStyles.viewer} ${className || ""}`,
18568
18657
  style: { height, width, ...style },
18569
18658
  children: [
18570
18659
  showControls && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
@@ -18580,7 +18669,7 @@ function PDFViewer({
18580
18669
  url
18581
18670
  }
18582
18671
  ),
18583
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: PDFViewer_default.content, children: [
18672
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: pdfViewerStyles.content, children: [
18584
18673
  showThumbnails && document2 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
18585
18674
  PDFThumbnails,
18586
18675
  {
@@ -18604,46 +18693,6 @@ function PDFViewer({
18604
18693
  }
18605
18694
  );
18606
18695
  }
18607
- async function isLinearizedPDF(url) {
18608
- try {
18609
- const response = await fetch(url, { headers: { Range: "bytes=0-1024" } });
18610
- const buffer = await response.arrayBuffer();
18611
- const view = new Uint8Array(buffer);
18612
- const text = new TextDecoder().decode(view);
18613
- return text.includes("Linearized");
18614
- } catch {
18615
- return false;
18616
- }
18617
- }
18618
- function downloadPDF(url, filename) {
18619
- const link = document.createElement("a");
18620
- link.href = url;
18621
- link.download = filename || "document.pdf";
18622
- document.body.appendChild(link);
18623
- link.click();
18624
- document.body.removeChild(link);
18625
- }
18626
- function calculateScaleForPageFit(pageWidth, pageHeight, containerWidth, containerHeight) {
18627
- const widthRatio = containerWidth / pageWidth;
18628
- const heightRatio = containerHeight / pageHeight;
18629
- return Math.min(widthRatio, heightRatio);
18630
- }
18631
- function formatFileSize(bytes) {
18632
- if (bytes === 0) return "0 Bytes";
18633
- const k = 1024;
18634
- const sizes = ["Bytes", "KB", "MB", "GB"];
18635
- const i = Math.floor(Math.log(bytes) / Math.log(k));
18636
- return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
18637
- }
18638
- async function extractPageText(pdfDoc, pageNumber) {
18639
- try {
18640
- const page = await pdfDoc.getPage(pageNumber);
18641
- const textContent = await page.getTextContent();
18642
- return textContent.items.filter((item) => "str" in item).map((item) => item.str).join(" ");
18643
- } catch {
18644
- return "";
18645
- }
18646
- }
18647
18696
  function getOptimalRangeHeader(fileSize) {
18648
18697
  const chunkSize = Math.min(65536, Math.ceil(fileSize * 0.1));
18649
18698
  return {
@@ -18668,9 +18717,9 @@ function createProgressiveFetchHandler(onProgress) {
18668
18717
  return response.arrayBuffer();
18669
18718
  };
18670
18719
  }
18671
- var import_react8, import_react9, import_react10, import_react11, import_react12, import_react13, import_react14, import_jsx_runtime5, import_jsx_runtime6, import_react15, import_jsx_runtime7, import_jsx_runtime8, DEFAULT_SCALE, CACHE_SIZE, MIN_ZOOM, MAX_ZOOM, ZOOM_STEP, PDFViewer_default, linearizedPDFConfig;
18720
+ var import_react8, import_react9, import_react10, import_react11, import_react12, import_react13, import_react14, import_jsx_runtime5, import_jsx_runtime6, import_react15, import_jsx_runtime7, import_jsx_runtime8, DEFAULT_SCALE, CACHE_SIZE, MIN_ZOOM, MAX_ZOOM, ZOOM_STEP, PDF_VIEWER_STYLES, stylesInjected, pdfViewerStyles, linearizedPDFConfig;
18672
18721
  var init_dist = __esm({
18673
- "node_modules/.pnpm/@page-speed+pdf-viewer@0.1.4_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js"() {
18722
+ "node_modules/.pnpm/@page-speed+pdf-viewer@0.1.6_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js"() {
18674
18723
  "use client";
18675
18724
  import_react8 = require("react");
18676
18725
  import_react9 = require("react");
@@ -18689,7 +18738,56 @@ var init_dist = __esm({
18689
18738
  MIN_ZOOM = 0.5;
18690
18739
  MAX_ZOOM = 3;
18691
18740
  ZOOM_STEP = 0.25;
18692
- PDFViewer_default = {
18741
+ PDF_VIEWER_STYLES = `
18742
+ /* Core viewer layout */
18743
+ .PDFViewer_viewer { display: flex; flex-direction: column; background: #f5f5f5; font-family: system-ui, -apple-system, sans-serif; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1); height: 100%; width: 100%; }
18744
+
18745
+ /* Controls */
18746
+ .PDFViewer_controls { display: flex; align-items: center; gap: 8px; padding: 12px 16px; background: #fff; border-bottom: 1px solid #e0e0e0; overflow-x: auto; flex-wrap: wrap; flex-shrink: 0; z-index: 10; position: relative; }
18747
+ .PDFViewer_controls button { padding: 8px 14px; background: #007bff; color: #fff; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; font-weight: 500; transition: background 150ms, box-shadow 150ms; white-space: nowrap; }
18748
+ .PDFViewer_controls button:hover:not(:disabled) { background: #0056b3; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
18749
+ .PDFViewer_controls button:disabled { opacity: 0.5; cursor: not-allowed; background: #6c757d; }
18750
+
18751
+ .PDFViewer_pageInput { width: 60px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; text-align: center; font-weight: 500; }
18752
+ .PDFViewer_pageInput:focus { outline: none; border-color: #007bff; box-shadow: 0 0 0 2px rgba(0,123,255,0.1); }
18753
+ .PDFViewer_pageTotal { font-size: 14px; color: #666; font-weight: 500; white-space: nowrap; }
18754
+ .PDFViewer_zoomLevel { font-size: 14px; color: #333; min-width: 60px; text-align: center; font-weight: 600; }
18755
+
18756
+ .PDFViewer_searchInput { padding: 6px 12px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; }
18757
+ .PDFViewer_searchResults { font-size: 12px; color: #666; }
18758
+
18759
+ .PDFViewer_button { padding: 6px 12px; background: #28a745; color: #fff; border: none; border-radius: 4px; text-decoration: none; cursor: pointer; transition: background 150ms; font-size: 14px; font-weight: 500; }
18760
+ .PDFViewer_button:hover { background: #218838; }
18761
+
18762
+ /* Main content */
18763
+ .PDFViewer_content { display: flex; flex: 1; overflow: hidden; min-height: 0; }
18764
+ .PDFViewer_canvas { flex: 1; overflow: auto; display: flex; align-items: center; justify-content: center; background: #fff; padding: 20px; }
18765
+ .PDFViewer_canvas canvas { max-width: 100%; height: auto !important; box-shadow: 0 2px 8px rgba(0,0,0,0.15); display: block; }
18766
+
18767
+ /* Thumbnails */
18768
+ .PDFViewer_thumbnails { width: 120px; overflow-y: auto; background: #fff; border-right: 1px solid #e0e0e0; padding: 8px; display: flex; flex-direction: column; gap: 8px; }
18769
+ .PDFViewer_thumbnail { position: relative; cursor: pointer; border: 2px solid transparent; border-radius: 4px; overflow: hidden; transition: border-color 150ms, box-shadow 150ms; }
18770
+ .PDFViewer_thumbnail:hover { border-color: #007bff; box-shadow: 0 2px 4px rgba(0,123,255,0.2); }
18771
+ .PDFViewer_thumbnail.PDFViewer_active { border-color: #007bff; box-shadow: 0 2px 8px rgba(0,123,255,0.4); }
18772
+ .PDFViewer_thumbnail canvas { width: 100%; height: auto; display: block; }
18773
+ .PDFViewer_pageNumber { position: absolute; bottom: 4px; right: 4px; font-size: 11px; background: rgba(0,0,0,0.7); color: #fff; padding: 2px 4px; border-radius: 2px; }
18774
+
18775
+ /* Loading & error */
18776
+ .PDFViewer_loading, .PDFViewer_error { display: flex; align-items: center; justify-content: center; background: #fff; border-radius: 8px; }
18777
+ .PDFViewer_loading p, .PDFViewer_error p { font-size: 16px; color: #666; }
18778
+ .PDFViewer_error p { color: #dc3545; }
18779
+
18780
+ /* Responsive tweaks */
18781
+ @media (max-width: 768px) {
18782
+ .PDFViewer_controls { gap: 6px; padding: 8px 12px; }
18783
+ .PDFViewer_controls button { padding: 4px 8px; font-size: 12px; }
18784
+ .PDFViewer_pageInput { width: 50px; }
18785
+ .PDFViewer_thumbnails { width: 80px; }
18786
+ .PDFViewer_searchInput { padding: 4px 8px; font-size: 12px; }
18787
+ }
18788
+ `;
18789
+ stylesInjected = false;
18790
+ pdfViewerStyles = {
18693
18791
  viewer: "PDFViewer_viewer",
18694
18792
  controls: "PDFViewer_controls",
18695
18793
  pageInput: "PDFViewer_pageInput",
@@ -22753,10 +22851,56 @@ function LightboxChrome({
22753
22851
  try {
22754
22852
  const response = await fetch(currentItem.src);
22755
22853
  const blob = await response.blob();
22854
+ const getFileExtension = () => {
22855
+ const contentType = response.headers.get("Content-Type");
22856
+ if (contentType) {
22857
+ const mimeToExt = {
22858
+ "application/pdf": ".pdf",
22859
+ "image/jpeg": ".jpg",
22860
+ "image/jpg": ".jpg",
22861
+ "image/png": ".png",
22862
+ "image/gif": ".gif",
22863
+ "image/webp": ".webp",
22864
+ "image/svg+xml": ".svg",
22865
+ "video/mp4": ".mp4",
22866
+ "video/webm": ".webm",
22867
+ "video/quicktime": ".mov"
22868
+ };
22869
+ const baseMime = contentType.split(";")[0].trim().toLowerCase();
22870
+ if (mimeToExt[baseMime]) {
22871
+ return mimeToExt[baseMime];
22872
+ }
22873
+ }
22874
+ try {
22875
+ const urlObj = new URL(currentItem.src, window.location.origin);
22876
+ const pathname = urlObj.pathname;
22877
+ const lastDotIndex = pathname.lastIndexOf(".");
22878
+ if (lastDotIndex > pathname.lastIndexOf("/")) {
22879
+ const ext = pathname.substring(lastDotIndex).toLowerCase();
22880
+ if (ext.length >= 2 && ext.length <= 6) {
22881
+ return ext;
22882
+ }
22883
+ }
22884
+ } catch {
22885
+ }
22886
+ const typeToExt = {
22887
+ "pdf": ".pdf",
22888
+ "image": ".jpg",
22889
+ "video": ".mp4"
22890
+ };
22891
+ if (currentItem.type && typeToExt[currentItem.type]) {
22892
+ return typeToExt[currentItem.type];
22893
+ }
22894
+ return "";
22895
+ };
22896
+ const baseName = currentItem.title || "download";
22897
+ const extension = getFileExtension();
22898
+ const hasExtension = baseName.includes(".") && baseName.lastIndexOf(".") > baseName.length - 6;
22899
+ const filename = hasExtension ? baseName : `${baseName}${extension}`;
22756
22900
  const url = window.URL.createObjectURL(blob);
22757
22901
  const link = document.createElement("a");
22758
22902
  link.href = url;
22759
- link.download = currentItem.title || "download";
22903
+ link.download = filename;
22760
22904
  document.body.appendChild(link);
22761
22905
  link.click();
22762
22906
  document.body.removeChild(link);