rita-workspace 0.5.11 → 0.5.13

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.js CHANGED
@@ -517,8 +517,11 @@ function WorkspaceProvider({ children, lang = "en" }) {
517
517
  const id = activeDrawingIdRef.current;
518
518
  if (id) {
519
519
  getDrawing(id).then((fresh) => {
520
- if (fresh && activeDrawingIdRef.current === id) {
521
- setActiveDrawing2(fresh);
520
+ if (fresh && activeDrawingIdRef.current === id && !prevConflictRef.current) {
521
+ setActiveDrawing2((prev) => {
522
+ if (!prev || prev.id !== id) return prev;
523
+ return { ...prev, name: fresh.name, folderId: fresh.folderId };
524
+ });
522
525
  }
523
526
  });
524
527
  }
@@ -579,11 +582,33 @@ function WorkspaceProvider({ children, lang = "en" }) {
579
582
  }
580
583
  };
581
584
  window.addEventListener("storage", onStorage);
582
- const intervalId = setInterval(recheckConflict, 5e3);
585
+ let intervalId = null;
586
+ const startPolling = () => {
587
+ if (!intervalId && drawingId) {
588
+ intervalId = setInterval(recheckConflict, 5e3);
589
+ }
590
+ };
591
+ const stopPolling = () => {
592
+ if (intervalId) {
593
+ clearInterval(intervalId);
594
+ intervalId = null;
595
+ }
596
+ };
597
+ const onVisibilityChange = () => {
598
+ if (document.hidden) {
599
+ stopPolling();
600
+ } else {
601
+ recheckConflict();
602
+ startPolling();
603
+ }
604
+ };
605
+ if (!document.hidden) startPolling();
606
+ document.addEventListener("visibilitychange", onVisibilityChange);
583
607
  return () => {
584
608
  channel?.close();
585
609
  window.removeEventListener("storage", onStorage);
586
- clearInterval(intervalId);
610
+ document.removeEventListener("visibilitychange", onVisibilityChange);
611
+ stopPolling();
587
612
  };
588
613
  }, [activeDrawing?.id]);
589
614
  (0, import_react.useEffect)(() => {
@@ -642,10 +667,12 @@ function WorkspaceProvider({ children, lang = "en" }) {
642
667
  const refreshDrawings = (0, import_react.useCallback)(async () => {
643
668
  if (!workspace) return;
644
669
  try {
645
- const allDrawings = await getAllDrawings();
670
+ const [allDrawings, allFolders] = await Promise.all([
671
+ getAllDrawings(),
672
+ getAllFolders()
673
+ ]);
646
674
  const wsDrawings = allDrawings.filter((d) => workspace.drawingIds.includes(d.id));
647
675
  setDrawings(wsDrawings);
648
- const allFolders = await getAllFolders();
649
676
  setFolders(allFolders);
650
677
  } catch (err) {
651
678
  }
@@ -1525,10 +1552,11 @@ var DrawingsDialog = ({
1525
1552
  const { rootDrawings, drawingsByFolder, filteredFolders } = (0, import_react5.useMemo)(() => {
1526
1553
  const query = searchQuery.toLowerCase().trim();
1527
1554
  const filtered = query ? drawings.filter((d) => d.name.toLowerCase().includes(query)) : drawings;
1528
- const root = filtered.filter((d) => !d.folderId);
1555
+ const sorted = [...filtered].sort((a, b) => a.createdAt - b.createdAt);
1556
+ const root = sorted.filter((d) => !d.folderId);
1529
1557
  const byFolder = {};
1530
1558
  for (const folder of folders) {
1531
- byFolder[folder.id] = filtered.filter((d) => d.folderId === folder.id);
1559
+ byFolder[folder.id] = sorted.filter((d) => d.folderId === folder.id);
1532
1560
  }
1533
1561
  const foldersFiltered = query ? folders.filter((f) => f.name.toLowerCase().includes(query) || (byFolder[f.id] || []).length > 0) : folders;
1534
1562
  return { rootDrawings: root, drawingsByFolder: byFolder, filteredFolders: foldersFiltered };
@@ -1570,16 +1598,6 @@ var DrawingsDialog = ({
1570
1598
  const renderDrawingRow = (drawing) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1571
1599
  "div",
1572
1600
  {
1573
- draggable: !editingId && !confirmDeleteId,
1574
- onDragStart: (e) => {
1575
- setDraggingDrawingId(drawing.id);
1576
- e.dataTransfer.effectAllowed = "move";
1577
- e.dataTransfer.setData("text/plain", drawing.id);
1578
- },
1579
- onDragEnd: () => {
1580
- setDraggingDrawingId(null);
1581
- setDropTargetFolderId(null);
1582
- },
1583
1601
  onMouseEnter: () => setHoveredId(drawing.id),
1584
1602
  onMouseLeave: () => setHoveredId(null),
1585
1603
  onClick: (e) => {
@@ -1594,13 +1612,40 @@ var DrawingsDialog = ({
1594
1612
  gap: "12px",
1595
1613
  borderRadius: "8px",
1596
1614
  marginBottom: "4px",
1597
- cursor: draggingDrawingId ? "grabbing" : "pointer",
1615
+ cursor: "pointer",
1598
1616
  backgroundColor: activeDrawing?.id === drawing.id ? "var(--color-primary-light, rgba(108, 99, 255, 0.1))" : selectedId === drawing.id ? "var(--color-primary-light, rgba(108, 99, 255, 0.06))" : "transparent",
1599
1617
  border: selectedId === drawing.id && activeDrawing?.id !== drawing.id ? "1px solid var(--color-primary, #6c63ff)" : "1px solid transparent",
1600
1618
  transition: "background-color 0.15s, border-color 0.15s",
1601
1619
  opacity: draggingDrawingId === drawing.id ? 0.4 : switchingId && switchingId !== drawing.id ? 0.5 : 1
1602
1620
  },
1603
1621
  children: [
1622
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1623
+ "span",
1624
+ {
1625
+ draggable: !editingId && !confirmDeleteId,
1626
+ onDragStart: (e) => {
1627
+ setDraggingDrawingId(drawing.id);
1628
+ e.dataTransfer.effectAllowed = "move";
1629
+ e.dataTransfer.setData("text/plain", drawing.id);
1630
+ },
1631
+ onDragEnd: () => {
1632
+ setDraggingDrawingId(null);
1633
+ setDropTargetFolderId(null);
1634
+ },
1635
+ onClick: (e) => e.stopPropagation(),
1636
+ style: {
1637
+ cursor: "grab",
1638
+ fontSize: "14px",
1639
+ color: "var(--text-secondary-color, #aaa)",
1640
+ flexShrink: 0,
1641
+ userSelect: "none",
1642
+ padding: "4px 2px",
1643
+ visibility: hoveredId === drawing.id || selectedId === drawing.id || draggingDrawingId === drawing.id ? "visible" : "hidden"
1644
+ },
1645
+ title: t.moveToFolder,
1646
+ children: "\u283F"
1647
+ }
1648
+ ),
1604
1649
  renderThumbnail && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
1605
1650
  width: "64px",
1606
1651
  height: "48px",
package/dist/index.mjs CHANGED
@@ -449,8 +449,11 @@ function WorkspaceProvider({ children, lang = "en" }) {
449
449
  const id = activeDrawingIdRef.current;
450
450
  if (id) {
451
451
  getDrawing(id).then((fresh) => {
452
- if (fresh && activeDrawingIdRef.current === id) {
453
- setActiveDrawing2(fresh);
452
+ if (fresh && activeDrawingIdRef.current === id && !prevConflictRef.current) {
453
+ setActiveDrawing2((prev) => {
454
+ if (!prev || prev.id !== id) return prev;
455
+ return { ...prev, name: fresh.name, folderId: fresh.folderId };
456
+ });
454
457
  }
455
458
  });
456
459
  }
@@ -511,11 +514,33 @@ function WorkspaceProvider({ children, lang = "en" }) {
511
514
  }
512
515
  };
513
516
  window.addEventListener("storage", onStorage);
514
- const intervalId = setInterval(recheckConflict, 5e3);
517
+ let intervalId = null;
518
+ const startPolling = () => {
519
+ if (!intervalId && drawingId) {
520
+ intervalId = setInterval(recheckConflict, 5e3);
521
+ }
522
+ };
523
+ const stopPolling = () => {
524
+ if (intervalId) {
525
+ clearInterval(intervalId);
526
+ intervalId = null;
527
+ }
528
+ };
529
+ const onVisibilityChange = () => {
530
+ if (document.hidden) {
531
+ stopPolling();
532
+ } else {
533
+ recheckConflict();
534
+ startPolling();
535
+ }
536
+ };
537
+ if (!document.hidden) startPolling();
538
+ document.addEventListener("visibilitychange", onVisibilityChange);
515
539
  return () => {
516
540
  channel?.close();
517
541
  window.removeEventListener("storage", onStorage);
518
- clearInterval(intervalId);
542
+ document.removeEventListener("visibilitychange", onVisibilityChange);
543
+ stopPolling();
519
544
  };
520
545
  }, [activeDrawing?.id]);
521
546
  useEffect(() => {
@@ -574,10 +599,12 @@ function WorkspaceProvider({ children, lang = "en" }) {
574
599
  const refreshDrawings = useCallback(async () => {
575
600
  if (!workspace) return;
576
601
  try {
577
- const allDrawings = await getAllDrawings();
602
+ const [allDrawings, allFolders] = await Promise.all([
603
+ getAllDrawings(),
604
+ getAllFolders()
605
+ ]);
578
606
  const wsDrawings = allDrawings.filter((d) => workspace.drawingIds.includes(d.id));
579
607
  setDrawings(wsDrawings);
580
- const allFolders = await getAllFolders();
581
608
  setFolders(allFolders);
582
609
  } catch (err) {
583
610
  }
@@ -1457,10 +1484,11 @@ var DrawingsDialog = ({
1457
1484
  const { rootDrawings, drawingsByFolder, filteredFolders } = useMemo(() => {
1458
1485
  const query = searchQuery.toLowerCase().trim();
1459
1486
  const filtered = query ? drawings.filter((d) => d.name.toLowerCase().includes(query)) : drawings;
1460
- const root = filtered.filter((d) => !d.folderId);
1487
+ const sorted = [...filtered].sort((a, b) => a.createdAt - b.createdAt);
1488
+ const root = sorted.filter((d) => !d.folderId);
1461
1489
  const byFolder = {};
1462
1490
  for (const folder of folders) {
1463
- byFolder[folder.id] = filtered.filter((d) => d.folderId === folder.id);
1491
+ byFolder[folder.id] = sorted.filter((d) => d.folderId === folder.id);
1464
1492
  }
1465
1493
  const foldersFiltered = query ? folders.filter((f) => f.name.toLowerCase().includes(query) || (byFolder[f.id] || []).length > 0) : folders;
1466
1494
  return { rootDrawings: root, drawingsByFolder: byFolder, filteredFolders: foldersFiltered };
@@ -1502,16 +1530,6 @@ var DrawingsDialog = ({
1502
1530
  const renderDrawingRow = (drawing) => /* @__PURE__ */ jsxs4(
1503
1531
  "div",
1504
1532
  {
1505
- draggable: !editingId && !confirmDeleteId,
1506
- onDragStart: (e) => {
1507
- setDraggingDrawingId(drawing.id);
1508
- e.dataTransfer.effectAllowed = "move";
1509
- e.dataTransfer.setData("text/plain", drawing.id);
1510
- },
1511
- onDragEnd: () => {
1512
- setDraggingDrawingId(null);
1513
- setDropTargetFolderId(null);
1514
- },
1515
1533
  onMouseEnter: () => setHoveredId(drawing.id),
1516
1534
  onMouseLeave: () => setHoveredId(null),
1517
1535
  onClick: (e) => {
@@ -1526,13 +1544,40 @@ var DrawingsDialog = ({
1526
1544
  gap: "12px",
1527
1545
  borderRadius: "8px",
1528
1546
  marginBottom: "4px",
1529
- cursor: draggingDrawingId ? "grabbing" : "pointer",
1547
+ cursor: "pointer",
1530
1548
  backgroundColor: activeDrawing?.id === drawing.id ? "var(--color-primary-light, rgba(108, 99, 255, 0.1))" : selectedId === drawing.id ? "var(--color-primary-light, rgba(108, 99, 255, 0.06))" : "transparent",
1531
1549
  border: selectedId === drawing.id && activeDrawing?.id !== drawing.id ? "1px solid var(--color-primary, #6c63ff)" : "1px solid transparent",
1532
1550
  transition: "background-color 0.15s, border-color 0.15s",
1533
1551
  opacity: draggingDrawingId === drawing.id ? 0.4 : switchingId && switchingId !== drawing.id ? 0.5 : 1
1534
1552
  },
1535
1553
  children: [
1554
+ /* @__PURE__ */ jsx6(
1555
+ "span",
1556
+ {
1557
+ draggable: !editingId && !confirmDeleteId,
1558
+ onDragStart: (e) => {
1559
+ setDraggingDrawingId(drawing.id);
1560
+ e.dataTransfer.effectAllowed = "move";
1561
+ e.dataTransfer.setData("text/plain", drawing.id);
1562
+ },
1563
+ onDragEnd: () => {
1564
+ setDraggingDrawingId(null);
1565
+ setDropTargetFolderId(null);
1566
+ },
1567
+ onClick: (e) => e.stopPropagation(),
1568
+ style: {
1569
+ cursor: "grab",
1570
+ fontSize: "14px",
1571
+ color: "var(--text-secondary-color, #aaa)",
1572
+ flexShrink: 0,
1573
+ userSelect: "none",
1574
+ padding: "4px 2px",
1575
+ visibility: hoveredId === drawing.id || selectedId === drawing.id || draggingDrawingId === drawing.id ? "visible" : "hidden"
1576
+ },
1577
+ title: t.moveToFolder,
1578
+ children: "\u283F"
1579
+ }
1580
+ ),
1536
1581
  renderThumbnail && /* @__PURE__ */ jsx6("div", { style: {
1537
1582
  width: "64px",
1538
1583
  height: "48px",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rita-workspace",
3
- "version": "0.5.11",
3
+ "version": "0.5.13",
4
4
  "description": "Multi-drawing workspace feature for Rita (Excalidraw fork)",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",