react-os-shell 0.2.50 → 0.2.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
- export { Files as default, openFilesInTrashMode } from './chunk-NXHJGQ7K.js';
2
- import './chunk-VTHYW6BX.js';
1
+ export { Files as default, openFilesInTrashMode } from './chunk-FTJFODBB.js';
2
+ import './chunk-6COZIC23.js';
3
3
  import './chunk-KUIPWCTJ.js';
4
4
  import './chunk-WIJ45SYD.js';
5
5
  import './chunk-VVXXHR5V.js';
6
6
  import './chunk-PLGHQ7QW.js';
7
- //# sourceMappingURL=Files-VZYDH4HD.js.map
8
- //# sourceMappingURL=Files-VZYDH4HD.js.map
7
+ //# sourceMappingURL=Files-DSNYMBYP.js.map
8
+ //# sourceMappingURL=Files-DSNYMBYP.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"Files-VZYDH4HD.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"Files-DSNYMBYP.js"}
@@ -0,0 +1,7 @@
1
+ export { Preview as default, setPdfPreview } from './chunk-6COZIC23.js';
2
+ import './chunk-KUIPWCTJ.js';
3
+ import './chunk-WIJ45SYD.js';
4
+ import './chunk-VVXXHR5V.js';
5
+ import './chunk-PLGHQ7QW.js';
6
+ //# sourceMappingURL=Preview-5B64EYL7.js.map
7
+ //# sourceMappingURL=Preview-5B64EYL7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"Preview-STZP7ZBD.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"Preview-5B64EYL7.js"}
@@ -1,5 +1,5 @@
1
- export { openFilesInTrashMode } from '../chunk-NXHJGQ7K.js';
2
- export { setPdfPreview } from '../chunk-VTHYW6BX.js';
1
+ export { openFilesInTrashMode } from '../chunk-FTJFODBB.js';
2
+ export { setPdfPreview } from '../chunk-6COZIC23.js';
3
3
  import '../chunk-KUIPWCTJ.js';
4
4
  import '../chunk-WIJ45SYD.js';
5
5
  import '../chunk-VVXXHR5V.js';
@@ -23,9 +23,9 @@ var Minesweeper = lazy(() => import('../Minesweeper-F7HUV7HZ.js'));
23
23
  var Email = lazy(() => import('../Email-RM5N27GG.js'));
24
24
  var GeminiChat = lazy(() => import('../GeminiChat-XTEBZIVK.js'));
25
25
  var Calendar = lazy(() => import('../Calendar-KIPFDLRZ.js'));
26
- var Preview = lazy(() => import('../Preview-STZP7ZBD.js'));
26
+ var Preview = lazy(() => import('../Preview-5B64EYL7.js'));
27
27
  var Documents = lazy(() => import('../Documents-3BIQRSXA.js'));
28
- var Files = lazy(() => import('../Files-VZYDH4HD.js'));
28
+ var Files = lazy(() => import('../Files-DSNYMBYP.js'));
29
29
  var Browser = lazy(() => import('../Browser-2TIJIWLC.js'));
30
30
  var utilityApps = {
31
31
  "/calculator": { component: Calculator, label: "Calculator", size: "sm", allowPinOnTop: true, utility: true, widget: true, autoHeight: true, dimensions: [280, 420] },
@@ -254,7 +254,8 @@ function PdfPanel({ url, filename, onDownload, onEmail }) {
254
254
  const [pdf, setPdf] = useState(null);
255
255
  const [page, setPage] = useState(1);
256
256
  const [totalPages, setTotalPages] = useState(0);
257
- const [scale, setScale] = useState(1.5);
257
+ const [scale, setScale] = useState(1);
258
+ const [fitMode, setFitMode] = useState(true);
258
259
  const [loading, setLoading] = useState(true);
259
260
  useEffect(() => {
260
261
  let cancelled = false;
@@ -275,14 +276,21 @@ function PdfPanel({ url, filename, onDownload, onEmail }) {
275
276
  };
276
277
  }, [url]);
277
278
  useEffect(() => {
278
- if (!pdf || !containerRef.current) return;
279
- pdf.getPage(1).then((p) => {
280
- const containerW = containerRef.current?.clientWidth || 800;
281
- const viewport = p.getViewport({ scale: 1 });
282
- const fitScale = (containerW - 40) / viewport.width;
283
- setScale(Math.min(Math.max(fitScale, 0.5), 3));
284
- });
285
- }, [pdf]);
279
+ if (!pdf || !fitMode || !containerRef.current) return;
280
+ const fit = () => {
281
+ if (!containerRef.current) return;
282
+ pdf.getPage(page).then((p) => {
283
+ const containerW = containerRef.current?.clientWidth || 800;
284
+ const viewport = p.getViewport({ scale: 1 });
285
+ const next = Math.min(Math.max((containerW - 40) / viewport.width, 0.3), 4);
286
+ setScale((prev) => Math.abs(prev - next) < 5e-3 ? prev : next);
287
+ });
288
+ };
289
+ fit();
290
+ const ro = new ResizeObserver(fit);
291
+ ro.observe(containerRef.current);
292
+ return () => ro.disconnect();
293
+ }, [pdf, page, fitMode]);
286
294
  useEffect(() => {
287
295
  if (!pdf || !canvasRef.current) return;
288
296
  let cancelled = false;
@@ -336,13 +344,49 @@ function PdfPanel({ url, filename, onDownload, onEmail }) {
336
344
  a.download = filename;
337
345
  a.click();
338
346
  };
339
- const fitWidth = () => {
340
- if (!pdf || !containerRef.current) return;
341
- pdf.getPage(page).then((p) => {
342
- const containerW = containerRef.current?.clientWidth || 800;
343
- const viewport = p.getViewport({ scale: 1 });
344
- setScale(Math.min(Math.max((containerW - 40) / viewport.width, 0.5), 3));
345
- });
347
+ const fitWidth = () => setFitMode(true);
348
+ const onWheelPage = (e) => {
349
+ if (!pdf) return;
350
+ if (e.ctrlKey || e.metaKey) return;
351
+ const el = containerRef.current;
352
+ if (!el) return;
353
+ const atTop = el.scrollTop <= 0;
354
+ const atBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 1;
355
+ if (e.deltaY > 0 && atBottom && page < totalPages) {
356
+ e.preventDefault();
357
+ setPage((p) => Math.min(totalPages, p + 1));
358
+ requestAnimationFrame(() => {
359
+ if (containerRef.current) containerRef.current.scrollTop = 0;
360
+ });
361
+ } else if (e.deltaY < 0 && atTop && page > 1) {
362
+ e.preventDefault();
363
+ setPage((p) => Math.max(1, p - 1));
364
+ requestAnimationFrame(() => {
365
+ if (containerRef.current) containerRef.current.scrollTop = containerRef.current.scrollHeight;
366
+ });
367
+ }
368
+ };
369
+ const onKeyPage = (e) => {
370
+ if (!pdf) return;
371
+ const tag = (document.activeElement?.tagName || "").toLowerCase();
372
+ if (tag === "input" || tag === "textarea" || document.activeElement?.isContentEditable) return;
373
+ if (e.key === "PageDown" || e.key === "ArrowRight") {
374
+ if (page < totalPages) {
375
+ e.preventDefault();
376
+ setPage((p) => Math.min(totalPages, p + 1));
377
+ }
378
+ } else if (e.key === "PageUp" || e.key === "ArrowLeft") {
379
+ if (page > 1) {
380
+ e.preventDefault();
381
+ setPage((p) => Math.max(1, p - 1));
382
+ }
383
+ } else if (e.key === "Home") {
384
+ e.preventDefault();
385
+ setPage(1);
386
+ } else if (e.key === "End") {
387
+ e.preventDefault();
388
+ setPage(totalPages);
389
+ }
346
390
  };
347
391
  const btn = "px-2 py-1 rounded hover:bg-gray-200 transition-colors text-gray-600 flex items-center gap-1";
348
392
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
@@ -355,19 +399,37 @@ function PdfPanel({ url, filename, onDownload, onEmail }) {
355
399
  ] }),
356
400
  /* @__PURE__ */ jsx("button", { onClick: () => setPage((p) => Math.min(totalPages, p + 1)), disabled: page >= totalPages, className: "px-1 py-1 rounded hover:bg-gray-200 disabled:opacity-30 text-gray-600", children: /* @__PURE__ */ jsx("svg", { className: "h-3.5 w-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8.25 4.5l7.5 7.5-7.5 7.5" }) }) }),
357
401
  /* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-gray-300 mx-1" }),
358
- /* @__PURE__ */ jsx("button", { onClick: () => setScale((s) => Math.max(0.3, Math.round((s - 0.25) * 100) / 100)), className: btn, children: "\u2212" }),
402
+ /* @__PURE__ */ jsx(
403
+ "button",
404
+ {
405
+ onClick: () => {
406
+ setFitMode(false);
407
+ setScale((s) => Math.max(0.3, Math.round((s - 0.25) * 100) / 100));
408
+ },
409
+ className: btn,
410
+ children: "\u2212"
411
+ }
412
+ ),
359
413
  /* @__PURE__ */ jsxs(
360
414
  "select",
361
415
  {
362
- value: ZOOM_PRESETS.includes(Math.round(scale * 100)) ? Math.round(scale * 100) : "custom",
416
+ value: fitMode ? "fit" : ZOOM_PRESETS.includes(Math.round(scale * 100)) ? Math.round(scale * 100) : "custom",
363
417
  onChange: (e) => {
364
418
  const v = e.target.value;
365
- if (v !== "custom") setScale(Number(v) / 100);
419
+ if (v === "fit") {
420
+ setFitMode(true);
421
+ return;
422
+ }
423
+ if (v !== "custom") {
424
+ setFitMode(false);
425
+ setScale(Number(v) / 100);
426
+ }
366
427
  },
367
428
  className: "bg-transparent hover:bg-gray-200 rounded px-1 py-1 text-gray-600 tabular-nums cursor-pointer focus:outline-none focus:ring-1 focus:ring-blue-400",
368
429
  title: "Zoom",
369
430
  children: [
370
- !ZOOM_PRESETS.includes(Math.round(scale * 100)) && /* @__PURE__ */ jsxs("option", { value: "custom", children: [
431
+ /* @__PURE__ */ jsx("option", { value: "fit", children: "Fit" }),
432
+ !fitMode && !ZOOM_PRESETS.includes(Math.round(scale * 100)) && /* @__PURE__ */ jsxs("option", { value: "custom", children: [
371
433
  Math.round(scale * 100),
372
434
  "%"
373
435
  ] }),
@@ -378,8 +440,26 @@ function PdfPanel({ url, filename, onDownload, onEmail }) {
378
440
  ]
379
441
  }
380
442
  ),
381
- /* @__PURE__ */ jsx("button", { onClick: () => setScale((s) => Math.min(4, Math.round((s + 0.25) * 100) / 100)), className: btn, children: "+" }),
382
- /* @__PURE__ */ jsx("button", { onClick: fitWidth, className: btn, children: "Fit" }),
443
+ /* @__PURE__ */ jsx(
444
+ "button",
445
+ {
446
+ onClick: () => {
447
+ setFitMode(false);
448
+ setScale((s) => Math.min(4, Math.round((s + 0.25) * 100) / 100));
449
+ },
450
+ className: btn,
451
+ children: "+"
452
+ }
453
+ ),
454
+ /* @__PURE__ */ jsx(
455
+ "button",
456
+ {
457
+ onClick: fitWidth,
458
+ className: btn + (fitMode ? " bg-gray-200 text-gray-900" : ""),
459
+ title: "Fit page width \u2014 auto-tracks the window size until you zoom manually",
460
+ children: "Fit"
461
+ }
462
+ ),
383
463
  /* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-gray-300 mx-1" }),
384
464
  /* @__PURE__ */ jsxs("button", { onClick: handlePrint, className: btn, children: [
385
465
  /* @__PURE__ */ jsx("svg", { className: "h-3.5 w-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6.72 13.829c-.24.03-.48.062-.72.096m.72-.096a42.415 42.415 0 0110.56 0m-10.56 0L6.34 18m10.94-4.171c.24.03.48.062.72.096m-.72-.096L17.66 18m0 0l.229 2.523a1.125 1.125 0 01-1.12 1.227H7.231c-.662 0-1.18-.568-1.12-1.227L6.34 18m11.318 0h1.091A2.25 2.25 0 0021 15.75V9.456c0-1.081-.768-2.015-1.837-2.175a48.055 48.055 0 00-1.913-.247M6.34 18H5.25A2.25 2.25 0 013 15.75V9.456c0-1.081.768-2.015 1.837-2.175a48.041 48.041 0 011.913-.247m10.5 0a48.536 48.536 0 00-10.5 0m10.5 0V3.375c0-.621-.504-1.125-1.125-1.125h-8.25c-.621 0-1.125.504-1.125 1.125v3.659M18 10.5h.008v.008H18V10.5zm-3 0h.008v.008H15V10.5z" }) }),
@@ -394,7 +474,17 @@ function PdfPanel({ url, filename, onDownload, onEmail }) {
394
474
  "Email"
395
475
  ] })
396
476
  ] }),
397
- /* @__PURE__ */ jsx("div", { ref: containerRef, className: "flex-1 overflow-auto bg-gray-100", children: loading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full text-gray-400 text-sm", children: "Loading PDF..." }) : /* @__PURE__ */ jsx("div", { className: "min-h-full flex items-center justify-center p-4", children: /* @__PURE__ */ jsx("canvas", { ref: canvasRef, className: "shadow-lg rounded" }) }) })
477
+ /* @__PURE__ */ jsx(
478
+ "div",
479
+ {
480
+ ref: containerRef,
481
+ className: "flex-1 overflow-auto bg-gray-100 outline-none",
482
+ tabIndex: 0,
483
+ onWheel: onWheelPage,
484
+ onKeyDown: onKeyPage,
485
+ children: loading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full text-gray-400 text-sm", children: "Loading PDF..." }) : /* @__PURE__ */ jsx("div", { className: "min-h-full flex items-center justify-center p-4", children: /* @__PURE__ */ jsx("canvas", { ref: canvasRef, className: "shadow-lg rounded" }) })
486
+ }
487
+ )
398
488
  ] });
399
489
  }
400
490
  var DEFAULT_DXF_FONTS = [
@@ -1427,8 +1517,8 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
1427
1517
  ny = sign * cos\u03B8;
1428
1518
  nz = sign * sin\u03B8;
1429
1519
  } else {
1430
- nx = sign * sin\u03B8;
1431
1520
  nz = sign * cos\u03B8;
1521
+ ny = sign * sin\u03B8;
1432
1522
  }
1433
1523
  const center = {
1434
1524
  x: (bbox.min.x + bbox.max.x) / 2,
@@ -1461,9 +1551,8 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
1461
1551
  if (!v?.viewer || loading || !containerRef.current) return;
1462
1552
  const renderer = v.viewer.renderer;
1463
1553
  const scene = v.viewer.scene;
1464
- const camera = v.viewer.camera;
1465
1554
  const canvas = renderer?.domElement;
1466
- if (!renderer || !scene || !camera || !canvas) return;
1555
+ if (!renderer || !scene || !canvas) return;
1467
1556
  let sampleMesh = null;
1468
1557
  v.viewer.mainModel?.EnumerateMeshes?.((m) => {
1469
1558
  if (!sampleMesh && !m.userData?.__sectionHelper && !m.userData?.__measureHelper) sampleMesh = m;
@@ -1674,6 +1763,8 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
1674
1763
  const updateLabel = () => {
1675
1764
  const s = measureRef.current;
1676
1765
  if (!s || s.points.length < 2 || !s.label) return;
1766
+ const camera = v.viewer.camera;
1767
+ if (!camera) return;
1677
1768
  const a = s.points[0], b = s.points[1];
1678
1769
  const mid = new Vector3Ctor((a.x + b.x) / 2, (a.y + b.y) / 2, (a.z + b.z) / 2);
1679
1770
  const projected = mid.clone();
@@ -1710,6 +1801,8 @@ function StepPanel({ url, filename, onDownload, onEmail }) {
1710
1801
  const doMeasurePick = (ev) => {
1711
1802
  const targets = collectTargets();
1712
1803
  if (!targets.length || !raycaster) return;
1804
+ const camera = v.viewer.camera;
1805
+ if (!camera) return;
1713
1806
  const ndc = ndcFromEvent(ev);
1714
1807
  raycaster.setFromCamera(ndc, camera);
1715
1808
  const hits = raycaster.intersectObjects(targets, false);
@@ -2310,5 +2403,5 @@ function ImagePanel({ url, filename, onDownload, onEmail }) {
2310
2403
  }
2311
2404
 
2312
2405
  export { Preview, setPdfPreview };
2313
- //# sourceMappingURL=chunk-VTHYW6BX.js.map
2314
- //# sourceMappingURL=chunk-VTHYW6BX.js.map
2406
+ //# sourceMappingURL=chunk-6COZIC23.js.map
2407
+ //# sourceMappingURL=chunk-6COZIC23.js.map