ssovee-os-web-ui 0.1.102 → 0.1.104

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/README.md CHANGED
@@ -107,7 +107,7 @@ export function NoteEditor() {
107
107
 
108
108
  ### PreviewComponent
109
109
 
110
- `PreviewComponent` previews a file from base64 data supplied by the host application. Pass either raw base64 or a complete data URL along with the original file name. Image files, PDFs, text files, and JSON are supported.
110
+ `PreviewComponent` previews a file from base64 data supplied by the host application. Pass either raw base64 or a complete data URL along with the original file name. Images, PDFs, text files, JSON, audio, and video use browser-native previews. Office and binary formats receive a download action because browsers cannot render them directly from base64 without a document parser.
111
111
 
112
112
  ```tsx
113
113
  import { PreviewComponent } from "ssovee-os-web-ui";
@@ -123,7 +123,7 @@ export function FilePreview({ fileName, base64 }: { fileName: string; base64: st
123
123
  }
124
124
  ```
125
125
 
126
- Supported image extensions include `avif`, `bmp`, `gif`, `jpg`, `jpeg`, `png`, `svg`, and `webp`. Supported text extensions include `css`, `csv`, `html`, `js`, `jsx`, `md`, `ts`, `tsx`, `txt`, `xml`, `yaml`, and `yml`.
126
+ Supported image extensions include `avif`, `bmp`, `gif`, `heic`, `jpg`, `jpeg`, `png`, `svg`, `tif`, `tiff`, and `webp`. Supported text extensions include common `c`, `cpp`, `css`, `csv`, `env`, `html`, `java`, `js`, `jsx`, `md`, `php`, `py`, `rb`, `rs`, `sh`, `sql`, `ts`, `tsx`, `txt`, `xml`, `yaml`, and `yml` files. Audio and video include common `aac`, `flac`, `m4a`, `mp3`, `ogg`, `wav`, `avi`, `m4v`, `mkv`, `mov`, `mp4`, `mpeg`, `ogv`, `webm`, and `wmv` files. Office formats such as `doc`, `docx`, `xls`, `xlsx`, `ppt`, and `pptx`, plus archives such as `zip`, `7z`, and `rar`, are available to download.
127
127
 
128
128
  ## Window components
129
129
 
package/dist/index.cjs CHANGED
@@ -7,7 +7,9 @@ var Editor = require('@monaco-editor/react');
7
7
  var react$1 = require('@tiptap/react');
8
8
  var StarterKit = require('@tiptap/starter-kit');
9
9
  var uaParserJs = require('ua-parser-js');
10
+ var reactPdf = require('react-pdf');
10
11
 
12
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
11
13
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
14
 
13
15
  function _interopNamespace(e) {
@@ -2318,12 +2320,20 @@ var Tabs = ({
2318
2320
  ] });
2319
2321
  };
2320
2322
  var Tabs_default = Tabs;
2321
- var imageExtensions = /\.(avif|bmp|gif|jpe?g|png|svg|webp)$/i;
2322
- var textExtensions = /\.(css|csv|html?|js|jsx|md|mjs|ts|tsx|txt|xml|yaml|yml)$/i;
2323
+ reactPdf.pdfjs.GlobalWorkerOptions.workerSrc = new URL(
2324
+ "pdfjs-dist/build/pdf.worker.min.mjs",
2325
+ (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))
2326
+ ).toString();
2327
+ var imageExtensions = /\.(avif|bmp|gif|heic|jpe?g|png|svg|tiff?|webp)$/i;
2328
+ var textExtensions = /\.(c|cc|conf|cpp|css|csv|env|h|hpp|html?|ini|java|js|jsx|log|md|mjs|php|py|rb|rs|sh|sql|swift|ts|tsx|txt|xml|yaml|yml)$/i;
2329
+ var audioExtensions = /\.(aac|flac|m4a|mp3|ogg|wav|weba)$/i;
2330
+ var videoExtensions = /\.(avi|m4v|mkv|mov|mp4|mpeg|ogv|webm|wmv)$/i;
2323
2331
  var getPreviewType = (fileName) => {
2324
2332
  if (/\.pdf$/i.test(fileName)) return "pdf";
2325
2333
  if (/\.json$/i.test(fileName)) return "json";
2326
2334
  if (imageExtensions.test(fileName)) return "image";
2335
+ if (audioExtensions.test(fileName)) return "audio";
2336
+ if (videoExtensions.test(fileName)) return "video";
2327
2337
  if (textExtensions.test(fileName) || !fileName.includes(".")) return "text";
2328
2338
  return "unsupported";
2329
2339
  };
@@ -2333,12 +2343,40 @@ var getMimeType = (fileName) => {
2333
2343
  avif: "image/avif",
2334
2344
  bmp: "image/bmp",
2335
2345
  gif: "image/gif",
2346
+ heic: "image/heic",
2336
2347
  jpeg: "image/jpeg",
2337
2348
  jpg: "image/jpeg",
2338
2349
  png: "image/png",
2339
2350
  svg: "image/svg+xml",
2351
+ tif: "image/tiff",
2352
+ tiff: "image/tiff",
2340
2353
  webp: "image/webp",
2341
- pdf: "application/pdf"
2354
+ pdf: "application/pdf",
2355
+ aac: "audio/aac",
2356
+ flac: "audio/flac",
2357
+ m4a: "audio/mp4",
2358
+ mp3: "audio/mpeg",
2359
+ ogg: "audio/ogg",
2360
+ wav: "audio/wav",
2361
+ weba: "audio/webm",
2362
+ avi: "video/x-msvideo",
2363
+ m4v: "video/mp4",
2364
+ mkv: "video/x-matroska",
2365
+ mov: "video/quicktime",
2366
+ mp4: "video/mp4",
2367
+ mpeg: "video/mpeg",
2368
+ ogv: "video/ogg",
2369
+ webm: "video/webm",
2370
+ wmv: "video/x-ms-wmv",
2371
+ doc: "application/msword",
2372
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
2373
+ xls: "application/vnd.ms-excel",
2374
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
2375
+ ppt: "application/vnd.ms-powerpoint",
2376
+ pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
2377
+ zip: "application/zip",
2378
+ "7z": "application/x-7z-compressed",
2379
+ rar: "application/vnd.rar"
2342
2380
  };
2343
2381
  return mimeTypes[extension ?? ""] ?? "application/octet-stream";
2344
2382
  };
@@ -2351,33 +2389,61 @@ var decodeBase64 = (base64) => {
2351
2389
  const bytes = Uint8Array.from(atob(value), (character) => character.charCodeAt(0));
2352
2390
  return new TextDecoder().decode(bytes);
2353
2391
  };
2354
- var toPdfBlob = (base64) => {
2392
+ var toPdfBytes = (base64) => {
2355
2393
  const value = base64.includes(",") ? base64.slice(base64.indexOf(",") + 1) : base64;
2356
- const bytes = Uint8Array.from(atob(value), (character) => character.charCodeAt(0));
2357
- return new Blob([bytes], { type: "application/pdf" });
2394
+ return Uint8Array.from(atob(value), (character) => character.charCodeAt(0));
2358
2395
  };
2359
2396
  var PreviewComponent = ({ fileName, base64, className }) => {
2360
2397
  const previewType = getPreviewType(fileName);
2361
2398
  const dataUrl = toDataUrl(base64, fileName);
2362
- const [pdfUrl, setPdfUrl] = React24.useState(dataUrl);
2363
- React24.useEffect(() => {
2364
- if (previewType !== "pdf" || typeof URL.createObjectURL !== "function") return;
2365
- try {
2366
- const objectUrl = URL.createObjectURL(toPdfBlob(base64));
2367
- setPdfUrl(objectUrl);
2368
- return () => URL.revokeObjectURL(objectUrl);
2369
- } catch {
2370
- setPdfUrl(dataUrl);
2371
- }
2372
- }, [base64, dataUrl, previewType]);
2399
+ const [pageCount, setPageCount] = React24.useState(null);
2400
+ const [pdfError, setPdfError] = React24.useState(false);
2373
2401
  if (previewType === "image") {
2374
2402
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex h-full min-h-48 w-full items-center justify-center overflow-auto", className), children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: dataUrl, alt: fileName, className: "max-h-full max-w-full object-contain" }) });
2375
2403
  }
2376
2404
  if (previewType === "pdf") {
2377
- return /* @__PURE__ */ jsxRuntime.jsx("object", { data: pdfUrl, type: "application/pdf", "aria-label": fileName, className: cn("h-full min-h-96 w-full", className), children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: pdfUrl, download: fileName, children: [
2378
- "Download ",
2379
- fileName
2380
- ] }) });
2405
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex min-h-96 flex-col items-center overflow-auto p-3", className), children: pdfError ? /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
2406
+ "Unable to render ",
2407
+ fileName,
2408
+ ". The PDF may be invalid or corrupted."
2409
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
2410
+ reactPdf.Document,
2411
+ {
2412
+ file: { data: toPdfBytes(base64) },
2413
+ loading: /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
2414
+ "Loading ",
2415
+ fileName,
2416
+ "..."
2417
+ ] }),
2418
+ error: /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
2419
+ "Unable to render ",
2420
+ fileName,
2421
+ ". The PDF may be invalid or corrupted."
2422
+ ] }),
2423
+ onLoadSuccess: ({ numPages }) => {
2424
+ setPageCount(numPages);
2425
+ setPdfError(false);
2426
+ },
2427
+ onLoadError: () => setPdfError(true),
2428
+ className: "flex w-full flex-col items-center",
2429
+ children: pageCount !== null && Array.from({ length: pageCount }, (_, index) => /* @__PURE__ */ jsxRuntime.jsx(
2430
+ reactPdf.Page,
2431
+ {
2432
+ pageNumber: index + 1,
2433
+ renderAnnotationLayer: false,
2434
+ renderTextLayer: false,
2435
+ className: "mb-3 max-w-full shadow-sm"
2436
+ },
2437
+ `${fileName}-${index + 1}`
2438
+ ))
2439
+ }
2440
+ ) });
2441
+ }
2442
+ if (previewType === "audio") {
2443
+ return /* @__PURE__ */ jsxRuntime.jsx("audio", { controls: true, src: dataUrl, className: cn("w-full", className) });
2444
+ }
2445
+ if (previewType === "video") {
2446
+ return /* @__PURE__ */ jsxRuntime.jsx("video", { controls: true, src: dataUrl, className: cn("max-h-full max-w-full", className) });
2381
2447
  }
2382
2448
  if (previewType === "text" || previewType === "json") {
2383
2449
  let content;
@@ -2394,7 +2460,7 @@ var PreviewComponent = ({ fileName, base64, className }) => {
2394
2460
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex min-h-48 items-center justify-center p-4 text-center", className), children: /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
2395
2461
  "Preview is not available for ",
2396
2462
  fileName,
2397
- "."
2463
+ ". This file format is not supported."
2398
2464
  ] }) });
2399
2465
  };
2400
2466
  var PreviewComponent_default = PreviewComponent;