@tutti-os/workbench-surface 0.0.17 → 0.0.19
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/{chunk-64XVF4I6.js → chunk-B5MSA47V.js} +19 -1
- package/dist/chunk-B5MSA47V.js.map +1 -0
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/index.d.ts +30 -7
- package/dist/index.js +1328 -193
- package/dist/index.js.map +1 -1
- package/dist/styles/workbench.css +163 -22
- package/dist/styles/workbenchStyle.test.ts +85 -3
- package/dist/{workbenchHostI18n-5xMPPBkf.d.ts → workbenchHostI18n-YFXDkIA1.d.ts} +1 -1
- package/package.json +5 -5
- package/dist/chunk-64XVF4I6.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
workbenchHostI18nResources,
|
|
6
6
|
workbenchWindowChromeI18nNamespace,
|
|
7
7
|
workbenchWindowChromeI18nResources
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-B5MSA47V.js";
|
|
9
9
|
|
|
10
10
|
// src/store/commands.ts
|
|
11
11
|
function createWorkbenchCommands(store) {
|
|
@@ -1417,6 +1417,7 @@ var inactiveMissionControlSnapshotSource = {
|
|
|
1417
1417
|
function useWorkbenchMissionControlState({
|
|
1418
1418
|
adapter,
|
|
1419
1419
|
mode,
|
|
1420
|
+
nodeIds,
|
|
1420
1421
|
onRequestClose
|
|
1421
1422
|
}) {
|
|
1422
1423
|
const isActive = mode !== null && adapter !== null;
|
|
@@ -1432,7 +1433,17 @@ function useWorkbenchMissionControlState({
|
|
|
1432
1433
|
);
|
|
1433
1434
|
const layoutConstraints = snapshot?.layoutConstraints ?? defaultWorkbenchLayoutConstraints;
|
|
1434
1435
|
const surfaceSize = snapshot?.surfaceSize ?? defaultWorkbenchSurfaceSize;
|
|
1435
|
-
const
|
|
1436
|
+
const scopedNodeIdSet = useMemo(
|
|
1437
|
+
() => nodeIds === void 0 ? null : new Set(nodeIds),
|
|
1438
|
+
[nodeIds]
|
|
1439
|
+
);
|
|
1440
|
+
const visibleNodes = useMemo(() => {
|
|
1441
|
+
const nextVisibleNodes = snapshot?.visibleNodes ?? [];
|
|
1442
|
+
if (scopedNodeIdSet === null) {
|
|
1443
|
+
return nextVisibleNodes;
|
|
1444
|
+
}
|
|
1445
|
+
return nextVisibleNodes.filter((node) => scopedNodeIdSet.has(node.id));
|
|
1446
|
+
}, [scopedNodeIdSet, snapshot?.visibleNodes]);
|
|
1436
1447
|
const [selectedNodeIds, setSelectedNodeIds] = useState3([]);
|
|
1437
1448
|
useEffect(() => {
|
|
1438
1449
|
if (mode === null) {
|
|
@@ -1511,13 +1522,13 @@ function useWorkbenchMissionControlState({
|
|
|
1511
1522
|
[adapter, onRequestClose]
|
|
1512
1523
|
);
|
|
1513
1524
|
const applyLayoutAndClose = useCallback2(
|
|
1514
|
-
(
|
|
1515
|
-
if (!adapter ||
|
|
1525
|
+
(nodeIds2, nextPreset) => {
|
|
1526
|
+
if (!adapter || nodeIds2.length < 2) {
|
|
1516
1527
|
return;
|
|
1517
1528
|
}
|
|
1518
1529
|
onRequestClose();
|
|
1519
1530
|
window.requestAnimationFrame(() => {
|
|
1520
|
-
adapter.applyLayoutPreset(
|
|
1531
|
+
adapter.applyLayoutPreset(nodeIds2, nextPreset);
|
|
1521
1532
|
});
|
|
1522
1533
|
},
|
|
1523
1534
|
[adapter, onRequestClose]
|
|
@@ -1561,9 +1572,17 @@ function useWorkbenchMissionControlState({
|
|
|
1561
1572
|
onNodePress: onPreviewPress,
|
|
1562
1573
|
selectedNodeIds: selectedNodeIdSet
|
|
1563
1574
|
},
|
|
1564
|
-
mode: "mission-control"
|
|
1575
|
+
mode: "mission-control",
|
|
1576
|
+
visibleNodeIds: new Set(orderedNodes.map((node) => node.id))
|
|
1565
1577
|
},
|
|
1566
|
-
[
|
|
1578
|
+
[
|
|
1579
|
+
mode,
|
|
1580
|
+
onPreviewPress,
|
|
1581
|
+
onRequestClose,
|
|
1582
|
+
orderedNodes,
|
|
1583
|
+
previewItems,
|
|
1584
|
+
selectedNodeIdSet
|
|
1585
|
+
]
|
|
1567
1586
|
);
|
|
1568
1587
|
useEffect(() => {
|
|
1569
1588
|
if (mode === null) {
|
|
@@ -1708,9 +1727,16 @@ function WorkbenchDockFrame({
|
|
|
1708
1727
|
const nodes = useWorkbenchSelector(
|
|
1709
1728
|
selectDockNodes
|
|
1710
1729
|
);
|
|
1730
|
+
const minimizedNodesWithPending = useMemo2(
|
|
1731
|
+
() => mergePendingMinimizedDockNode(
|
|
1732
|
+
nodes.filter((node) => node.isMinimized),
|
|
1733
|
+
genie.pendingMinimizedNode
|
|
1734
|
+
),
|
|
1735
|
+
[genie.pendingMinimizedNode, nodes]
|
|
1736
|
+
);
|
|
1711
1737
|
const minimizedNodes = useMemo2(
|
|
1712
|
-
() =>
|
|
1713
|
-
[
|
|
1738
|
+
() => minimizedNodesWithPending.filter((node) => node.isMinimized),
|
|
1739
|
+
[minimizedNodesWithPending]
|
|
1714
1740
|
);
|
|
1715
1741
|
const focusedNodeId = useWorkbenchSelector(
|
|
1716
1742
|
(state) => selectFocusedWorkbenchNode(state)?.id ?? null
|
|
@@ -1752,6 +1778,9 @@ function WorkbenchDockFrame({
|
|
|
1752
1778
|
},
|
|
1753
1779
|
shouldAnimateMinimizedDockEnter: (nodeID) => {
|
|
1754
1780
|
return genie.shouldAnimateMinimizedDockEnter(nodeID);
|
|
1781
|
+
},
|
|
1782
|
+
isPendingMinimizedDockNode: (nodeID) => {
|
|
1783
|
+
return genie.isPendingMinimizedDockNode(nodeID);
|
|
1755
1784
|
}
|
|
1756
1785
|
},
|
|
1757
1786
|
minimizedNodes,
|
|
@@ -1761,6 +1790,16 @@ function WorkbenchDockFrame({
|
|
|
1761
1790
|
)
|
|
1762
1791
|
] });
|
|
1763
1792
|
}
|
|
1793
|
+
function mergePendingMinimizedDockNode(nodes, pendingNode) {
|
|
1794
|
+
if (!pendingNode) {
|
|
1795
|
+
return nodes;
|
|
1796
|
+
}
|
|
1797
|
+
const existingNode = nodes.find((node) => node.id === pendingNode.id);
|
|
1798
|
+
if (existingNode?.isMinimized) {
|
|
1799
|
+
return nodes;
|
|
1800
|
+
}
|
|
1801
|
+
return [...nodes.filter((node) => node.id !== pendingNode.id), pendingNode];
|
|
1802
|
+
}
|
|
1764
1803
|
|
|
1765
1804
|
// src/react/WorkbenchNodeLayer.tsx
|
|
1766
1805
|
import { memo, useMemo as useMemo3 } from "react";
|
|
@@ -2086,7 +2125,8 @@ function WorkbenchWindowFrame({
|
|
|
2086
2125
|
const resolvedFullscreenHeaderMode = fullscreenHeaderMode ?? "reveal";
|
|
2087
2126
|
const presentationMode = presentation?.mode ?? null;
|
|
2088
2127
|
const presentationFrame = presentation?.frameByNodeId.get(node.id) ?? null;
|
|
2089
|
-
const
|
|
2128
|
+
const isPresentationHidden = presentationMode === "mission-control" && !presentation?.visibleNodeIds.has(node.id);
|
|
2129
|
+
const presentationInteraction = interactive && presentationMode === "mission-control" && !isPresentationHidden ? presentation?.interaction ?? null : null;
|
|
2090
2130
|
const isMissionControlSelected = presentationInteraction?.selectedNodeIds.has(node.id) ?? false;
|
|
2091
2131
|
const presentationScale = presentationMode === "mission-control" && presentationFrame ? Math.min(
|
|
2092
2132
|
presentationFrame.width / Math.max(1, node.frame.width),
|
|
@@ -2100,11 +2140,11 @@ function WorkbenchWindowFrame({
|
|
|
2100
2140
|
0,
|
|
2101
2141
|
(presentationFrame.height - node.frame.height * presentationScale) / 2
|
|
2102
2142
|
) - node.frame.y : 0;
|
|
2103
|
-
const shellTransform = presentationMode === "mission-control" ? `matrix(${presentationScale}, 0, 0, ${presentationScale}, ${presentationOffsetX}, ${presentationOffsetY})` : void 0;
|
|
2143
|
+
const shellTransform = presentationMode === "mission-control" && presentationFrame ? `matrix(${presentationScale}, 0, 0, ${presentationScale}, ${presentationOffsetX}, ${presentationOffsetY})` : void 0;
|
|
2104
2144
|
return /* @__PURE__ */ jsxs2(
|
|
2105
2145
|
"section",
|
|
2106
2146
|
{
|
|
2107
|
-
"aria-hidden": hiddenMounted ? true : void 0,
|
|
2147
|
+
"aria-hidden": hiddenMounted || isPresentationHidden ? true : void 0,
|
|
2108
2148
|
className: "workbench-window-shell",
|
|
2109
2149
|
"data-focused": isFocused ? "true" : "false",
|
|
2110
2150
|
"data-display-mode": node.displayMode,
|
|
@@ -2112,6 +2152,7 @@ function WorkbenchWindowFrame({
|
|
|
2112
2152
|
"data-launch-source": resolveWorkbenchNodeLaunchSource(node.data),
|
|
2113
2153
|
"data-minimized-mount": hiddenMounted ? "hidden" : "visible",
|
|
2114
2154
|
"data-presentation-mode": presentationMode ?? "default",
|
|
2155
|
+
"data-presentation-visibility": isPresentationHidden ? "hidden" : "visible",
|
|
2115
2156
|
"data-slot": "viewport-menu-boundary",
|
|
2116
2157
|
"data-workbench-node-type-id": resolveWorkbenchNodeTypeId(node.data),
|
|
2117
2158
|
"data-workbench-window-id": node.id,
|
|
@@ -2126,7 +2167,7 @@ function WorkbenchWindowFrame({
|
|
|
2126
2167
|
width: node.frame.width,
|
|
2127
2168
|
zIndex
|
|
2128
2169
|
},
|
|
2129
|
-
onPointerDown: hiddenMounted || !interactive || presentationMode === "mission-control" ? void 0 : () => controller.commands.focusNode(node.id),
|
|
2170
|
+
onPointerDown: hiddenMounted || isPresentationHidden || !interactive || presentationMode === "mission-control" ? void 0 : () => controller.commands.focusNode(node.id),
|
|
2130
2171
|
children: [
|
|
2131
2172
|
/* @__PURE__ */ jsx5("div", { className: "workbench-window-shell__content", children: /* @__PURE__ */ jsxs2(
|
|
2132
2173
|
"div",
|
|
@@ -2505,41 +2546,143 @@ function resolveGenieDirtyRect({
|
|
|
2505
2546
|
width: Math.max(0, right - left)
|
|
2506
2547
|
};
|
|
2507
2548
|
}
|
|
2549
|
+
function resolveGenieRowProgress({
|
|
2550
|
+
direction,
|
|
2551
|
+
progress,
|
|
2552
|
+
rowProgress,
|
|
2553
|
+
stagger
|
|
2554
|
+
}) {
|
|
2555
|
+
const start = direction === "minimize" ? (1 - rowProgress) * stagger : rowProgress * stagger;
|
|
2556
|
+
return clampGenieProgress((progress - start) / (1 - start));
|
|
2557
|
+
}
|
|
2558
|
+
function resolveGenieRowTargetY({
|
|
2559
|
+
direction,
|
|
2560
|
+
dockPoint,
|
|
2561
|
+
progress,
|
|
2562
|
+
sourceY,
|
|
2563
|
+
textureHeight,
|
|
2564
|
+
textureRect
|
|
2565
|
+
}) {
|
|
2566
|
+
const rowProgress = clampGenieProgress(sourceY / textureHeight);
|
|
2567
|
+
const verticalProgress = resolveGenieRowProgress({
|
|
2568
|
+
direction,
|
|
2569
|
+
progress,
|
|
2570
|
+
rowProgress,
|
|
2571
|
+
stagger: genieVerticalRowStagger
|
|
2572
|
+
});
|
|
2573
|
+
const verticalEase = easeInQuadratic(verticalProgress);
|
|
2574
|
+
return direction === "minimize" ? lerpGenieValue(textureRect.top + sourceY, dockPoint.y, verticalEase) : lerpGenieValue(dockPoint.y, textureRect.top + sourceY, verticalEase);
|
|
2575
|
+
}
|
|
2508
2576
|
function canInlineComputedStyle(element) {
|
|
2509
2577
|
return element instanceof HTMLElement || typeof SVGElement !== "undefined" && element instanceof SVGElement;
|
|
2510
2578
|
}
|
|
2511
|
-
function
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2579
|
+
function isHiddenForGenieTexture(computed) {
|
|
2580
|
+
return computed.display === "none" || computed.visibility === "hidden" || computed.visibility === "collapse" || Number.parseFloat(computed.opacity || "1") <= 0;
|
|
2581
|
+
}
|
|
2582
|
+
function rectsIntersect(a, b) {
|
|
2583
|
+
return a.left < b.left + b.width && a.left + a.width > b.left && a.top < b.top + b.height && a.top + a.height > b.top;
|
|
2584
|
+
}
|
|
2585
|
+
function resolveElementSkipReasonForGenieTexture(element, rootRect, computed) {
|
|
2586
|
+
if (isHiddenForGenieTexture(computed)) {
|
|
2587
|
+
return "hidden";
|
|
2588
|
+
}
|
|
2589
|
+
const tagName = element.tagName.toLowerCase();
|
|
2590
|
+
if (tagName === "script" || tagName === "style" || tagName === "template") {
|
|
2591
|
+
return "unsupported";
|
|
2592
|
+
}
|
|
2593
|
+
const rect = element.getBoundingClientRect();
|
|
2594
|
+
if (rect.width <= 0 || rect.height <= 0) {
|
|
2595
|
+
return "zero-size";
|
|
2596
|
+
}
|
|
2597
|
+
return rectsIntersect(
|
|
2598
|
+
{
|
|
2599
|
+
height: rect.height,
|
|
2600
|
+
left: rect.left,
|
|
2601
|
+
top: rect.top,
|
|
2602
|
+
width: rect.width
|
|
2603
|
+
},
|
|
2604
|
+
rootRect
|
|
2605
|
+
) ? null : "offscreen";
|
|
2606
|
+
}
|
|
2607
|
+
function hasMeaningfulTextNode(node) {
|
|
2608
|
+
return node.textContent?.trim() ? true : false;
|
|
2609
|
+
}
|
|
2610
|
+
function cloneMeaningfulGenieNode(source, rootRect, images, forceInclude = false) {
|
|
2611
|
+
if (source.nodeType === Node.TEXT_NODE) {
|
|
2612
|
+
if (!hasMeaningfulTextNode(source)) {
|
|
2613
|
+
return null;
|
|
2614
|
+
}
|
|
2615
|
+
return source.cloneNode(false);
|
|
2616
|
+
}
|
|
2617
|
+
if (source.nodeType !== Node.ELEMENT_NODE) {
|
|
2618
|
+
return null;
|
|
2619
|
+
}
|
|
2620
|
+
const sourceElement = source;
|
|
2621
|
+
if (!canInlineComputedStyle(sourceElement)) {
|
|
2622
|
+
return null;
|
|
2623
|
+
}
|
|
2624
|
+
const computed = window.getComputedStyle(sourceElement);
|
|
2625
|
+
const skipReason = resolveElementSkipReasonForGenieTexture(
|
|
2626
|
+
sourceElement,
|
|
2627
|
+
rootRect,
|
|
2628
|
+
computed
|
|
2629
|
+
);
|
|
2630
|
+
const includeSelf = forceInclude || skipReason === null;
|
|
2631
|
+
if (!includeSelf && skipReason === "hidden") {
|
|
2632
|
+
return null;
|
|
2633
|
+
}
|
|
2634
|
+
const clone = sourceElement.cloneNode(false);
|
|
2635
|
+
copyGenieComputedStyle(sourceElement, clone, computed);
|
|
2636
|
+
for (const child of Array.from(source.childNodes)) {
|
|
2637
|
+
const childClone = cloneMeaningfulGenieNode(child, rootRect, images);
|
|
2638
|
+
if (childClone) {
|
|
2639
|
+
clone.appendChild(childClone);
|
|
2528
2640
|
}
|
|
2529
|
-
clone.style.animation = "none";
|
|
2530
|
-
clone.style.opacity = "1";
|
|
2531
|
-
clone.style.transition = "none";
|
|
2532
|
-
clone.style.visibility = "visible";
|
|
2533
2641
|
}
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
const
|
|
2539
|
-
|
|
2540
|
-
|
|
2642
|
+
if (!includeSelf && clone.childNodes.length === 0) {
|
|
2643
|
+
return null;
|
|
2644
|
+
}
|
|
2645
|
+
if (sourceElement instanceof HTMLImageElement) {
|
|
2646
|
+
const rect = sourceElement.getBoundingClientRect();
|
|
2647
|
+
images.push({
|
|
2648
|
+
displayHeight: rect.height,
|
|
2649
|
+
displayWidth: rect.width,
|
|
2650
|
+
url: sourceElement.currentSrc || sourceElement.src || sourceElement.getAttribute("src") || null
|
|
2651
|
+
});
|
|
2652
|
+
}
|
|
2653
|
+
return clone;
|
|
2654
|
+
}
|
|
2655
|
+
function copyGenieComputedStyle(source, clone, computed = window.getComputedStyle(source)) {
|
|
2656
|
+
if (!canInlineComputedStyle(source) || !canInlineComputedStyle(clone)) {
|
|
2657
|
+
return;
|
|
2658
|
+
}
|
|
2659
|
+
if (computed.cssText) {
|
|
2660
|
+
clone.style.cssText = computed.cssText;
|
|
2661
|
+
} else {
|
|
2662
|
+
for (let index = 0; index < computed.length; index += 1) {
|
|
2663
|
+
const propertyName = computed.item(index);
|
|
2664
|
+
if (!propertyName) {
|
|
2665
|
+
continue;
|
|
2666
|
+
}
|
|
2667
|
+
clone.style.setProperty(
|
|
2668
|
+
propertyName,
|
|
2669
|
+
computed.getPropertyValue(propertyName),
|
|
2670
|
+
computed.getPropertyPriority(propertyName)
|
|
2671
|
+
);
|
|
2541
2672
|
}
|
|
2542
2673
|
}
|
|
2674
|
+
clone.style.animation = "none";
|
|
2675
|
+
clone.style.opacity = "1";
|
|
2676
|
+
clone.style.transition = "none";
|
|
2677
|
+
clone.style.visibility = "visible";
|
|
2678
|
+
}
|
|
2679
|
+
function cloneMeaningfulGenieElement(source, rootRect) {
|
|
2680
|
+
const images = [];
|
|
2681
|
+
const clone = cloneMeaningfulGenieNode(source, rootRect, images, true);
|
|
2682
|
+
if (!(clone instanceof HTMLElement)) {
|
|
2683
|
+
return null;
|
|
2684
|
+
}
|
|
2685
|
+
return { clone, images };
|
|
2543
2686
|
}
|
|
2544
2687
|
function renderGenieScanlines(context, viewportWidth, viewportHeight, frame) {
|
|
2545
2688
|
const { direction, dockPoint, texture, textureRect } = frame;
|
|
@@ -2563,16 +2706,13 @@ function renderGenieScanlines(context, viewportWidth, viewportHeight, frame) {
|
|
|
2563
2706
|
const sourceHeight = Math.min(scanlineStride, textureHeight - y);
|
|
2564
2707
|
const sourceMidY = y + sourceHeight / 2;
|
|
2565
2708
|
const rowProgress = sourceMidY / textureHeight;
|
|
2566
|
-
const
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2709
|
+
const horizontalProgress = resolveGenieRowProgress({
|
|
2710
|
+
direction,
|
|
2711
|
+
progress,
|
|
2712
|
+
rowProgress,
|
|
2713
|
+
stagger: genieHorizontalRowStagger
|
|
2714
|
+
});
|
|
2570
2715
|
const horizontalEase = easeInOutCubic(horizontalProgress);
|
|
2571
|
-
const verticalStart = direction === "minimize" ? (1 - rowProgress) * genieVerticalRowStagger : rowProgress * genieVerticalRowStagger;
|
|
2572
|
-
const verticalProgress = clampGenieProgress(
|
|
2573
|
-
(progress - verticalStart) / (1 - verticalStart)
|
|
2574
|
-
);
|
|
2575
|
-
const verticalEase = easeInQuadratic(verticalProgress);
|
|
2576
2716
|
const left = direction === "minimize" ? lerpGenieValue(textureRect.left, dockPoint.x, horizontalEase) : lerpGenieValue(dockPoint.x, textureRect.left, horizontalEase);
|
|
2577
2717
|
const right = direction === "minimize" ? lerpGenieValue(
|
|
2578
2718
|
textureRect.left + textureWidth,
|
|
@@ -2583,15 +2723,24 @@ function renderGenieScanlines(context, viewportWidth, viewportHeight, frame) {
|
|
|
2583
2723
|
textureRect.left + textureWidth,
|
|
2584
2724
|
horizontalEase
|
|
2585
2725
|
);
|
|
2586
|
-
const
|
|
2587
|
-
|
|
2588
|
-
dockPoint
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
textureRect
|
|
2593
|
-
|
|
2594
|
-
|
|
2726
|
+
const targetTop = resolveGenieRowTargetY({
|
|
2727
|
+
direction,
|
|
2728
|
+
dockPoint,
|
|
2729
|
+
progress,
|
|
2730
|
+
sourceY: y,
|
|
2731
|
+
textureHeight,
|
|
2732
|
+
textureRect
|
|
2733
|
+
});
|
|
2734
|
+
const targetBottom = resolveGenieRowTargetY({
|
|
2735
|
+
direction,
|
|
2736
|
+
dockPoint,
|
|
2737
|
+
progress,
|
|
2738
|
+
sourceY: y + sourceHeight,
|
|
2739
|
+
textureHeight,
|
|
2740
|
+
textureRect
|
|
2741
|
+
});
|
|
2742
|
+
const targetY = Math.min(targetTop, targetBottom) - 0.5;
|
|
2743
|
+
const targetHeight = Math.max(1, Math.abs(targetBottom - targetTop) + 1);
|
|
2595
2744
|
const rowWidth = right - left;
|
|
2596
2745
|
if (rowWidth < 0.8) {
|
|
2597
2746
|
continue;
|
|
@@ -2605,7 +2754,7 @@ function renderGenieScanlines(context, viewportWidth, viewportHeight, frame) {
|
|
|
2605
2754
|
left,
|
|
2606
2755
|
targetY,
|
|
2607
2756
|
rowWidth,
|
|
2608
|
-
|
|
2757
|
+
targetHeight
|
|
2609
2758
|
);
|
|
2610
2759
|
}
|
|
2611
2760
|
const glowProgress = direction === "minimize" ? progress : 1 - progress;
|
|
@@ -2635,6 +2784,7 @@ function renderGenieScanlines(context, viewportWidth, viewportHeight, frame) {
|
|
|
2635
2784
|
// src/react/useWorkbenchGenieAnimation.tsx
|
|
2636
2785
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
2637
2786
|
var genieDurationMs = 400;
|
|
2787
|
+
var scaleMinimizeDurationMs = 220;
|
|
2638
2788
|
var genieMaxDevicePixelRatio = 2;
|
|
2639
2789
|
var genieSnapshotScale = 1;
|
|
2640
2790
|
var minimizedDockSlotEnterAnimationMs = 720;
|
|
@@ -2643,6 +2793,7 @@ var dockPreviewMaxHeight = 170;
|
|
|
2643
2793
|
var dockPreviewImageCacheMaxEntries = 96;
|
|
2644
2794
|
var inlineImageResourceCacheMaxEntries = 160;
|
|
2645
2795
|
var dockAnchorFallbackSizePx = 43.2;
|
|
2796
|
+
var genieInlineImageMaxDevicePixelRatio = 2;
|
|
2646
2797
|
var dockPreviewImageByNodeID = /* @__PURE__ */ new Map();
|
|
2647
2798
|
var inlineImageResourceByUrl = /* @__PURE__ */ new Map();
|
|
2648
2799
|
function resolveWorkbenchCaptureElement(windowElement) {
|
|
@@ -2683,9 +2834,6 @@ function blobToDataUrl(blob) {
|
|
|
2683
2834
|
reader.readAsDataURL(blob);
|
|
2684
2835
|
});
|
|
2685
2836
|
}
|
|
2686
|
-
function resolveImageResourceUrl(image) {
|
|
2687
|
-
return image.currentSrc || image.src || image.getAttribute("src") || null;
|
|
2688
|
-
}
|
|
2689
2837
|
async function fetchInlineImageResource(imageUrl) {
|
|
2690
2838
|
try {
|
|
2691
2839
|
const response = await fetch(imageUrl);
|
|
@@ -2721,21 +2869,31 @@ function readInlineImageResource(imageUrl) {
|
|
|
2721
2869
|
}
|
|
2722
2870
|
async function inlineCloneImageResources({
|
|
2723
2871
|
cloneRoot,
|
|
2724
|
-
|
|
2872
|
+
images
|
|
2725
2873
|
}) {
|
|
2726
2874
|
const cloneImages = Array.from(cloneRoot.querySelectorAll("img"));
|
|
2727
2875
|
await Promise.all(
|
|
2728
|
-
|
|
2876
|
+
images.map(async (imageInfo, index) => {
|
|
2729
2877
|
const cloneImage = cloneImages[index];
|
|
2730
2878
|
if (!cloneImage) {
|
|
2731
2879
|
return;
|
|
2732
2880
|
}
|
|
2733
2881
|
cloneImage.removeAttribute("srcset");
|
|
2734
2882
|
cloneImage.removeAttribute("sizes");
|
|
2883
|
+
const imageUrl = imageInfo.url;
|
|
2735
2884
|
if (!imageUrl) {
|
|
2736
2885
|
return;
|
|
2737
2886
|
}
|
|
2738
|
-
|
|
2887
|
+
const inlineImageUrl = await readInlineImageResource(imageUrl) ?? imageUrl;
|
|
2888
|
+
const resizedImageUrl = await resizeInlineImageResourceForGenieTexture(
|
|
2889
|
+
inlineImageUrl,
|
|
2890
|
+
imageInfo
|
|
2891
|
+
);
|
|
2892
|
+
if (resizedImageUrl && resizedImageUrl !== inlineImageUrl) {
|
|
2893
|
+
cloneImage.src = resizedImageUrl;
|
|
2894
|
+
return;
|
|
2895
|
+
}
|
|
2896
|
+
cloneImage.src = inlineImageUrl;
|
|
2739
2897
|
})
|
|
2740
2898
|
);
|
|
2741
2899
|
}
|
|
@@ -2745,16 +2903,61 @@ async function loadImageFromSvg(svg) {
|
|
|
2745
2903
|
await image.decode();
|
|
2746
2904
|
return image;
|
|
2747
2905
|
}
|
|
2906
|
+
function resolveGenieInlineImageTargetSize({
|
|
2907
|
+
displayHeight,
|
|
2908
|
+
displayWidth
|
|
2909
|
+
}) {
|
|
2910
|
+
if (displayWidth <= 0 || displayHeight <= 0) {
|
|
2911
|
+
return null;
|
|
2912
|
+
}
|
|
2913
|
+
const scale = Math.min(
|
|
2914
|
+
window.devicePixelRatio || 1,
|
|
2915
|
+
genieInlineImageMaxDevicePixelRatio
|
|
2916
|
+
);
|
|
2917
|
+
return {
|
|
2918
|
+
height: Math.max(1, Math.ceil(displayHeight * scale)),
|
|
2919
|
+
width: Math.max(1, Math.ceil(displayWidth * scale))
|
|
2920
|
+
};
|
|
2921
|
+
}
|
|
2922
|
+
async function resizeInlineImageResourceForGenieTexture(imageUrl, imageInfo) {
|
|
2923
|
+
const targetSize = resolveGenieInlineImageTargetSize(imageInfo);
|
|
2924
|
+
if (!targetSize) {
|
|
2925
|
+
return null;
|
|
2926
|
+
}
|
|
2927
|
+
const image = new Image();
|
|
2928
|
+
image.src = imageUrl;
|
|
2929
|
+
try {
|
|
2930
|
+
await image.decode();
|
|
2931
|
+
} catch {
|
|
2932
|
+
return null;
|
|
2933
|
+
}
|
|
2934
|
+
if (image.naturalWidth <= targetSize.width && image.naturalHeight <= targetSize.height) {
|
|
2935
|
+
return null;
|
|
2936
|
+
}
|
|
2937
|
+
const canvas = document.createElement("canvas");
|
|
2938
|
+
canvas.width = targetSize.width;
|
|
2939
|
+
canvas.height = targetSize.height;
|
|
2940
|
+
const context = canvas.getContext("2d");
|
|
2941
|
+
if (!context) {
|
|
2942
|
+
return null;
|
|
2943
|
+
}
|
|
2944
|
+
try {
|
|
2945
|
+
context.drawImage(image, 0, 0, targetSize.width, targetSize.height);
|
|
2946
|
+
return canvas.toDataURL("image/png");
|
|
2947
|
+
} catch {
|
|
2948
|
+
return null;
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2748
2951
|
function prepareElementTextureCapture(element) {
|
|
2749
2952
|
const windowRect = viewportRectFromElement(element);
|
|
2750
2953
|
if (!isUsableGenieRect(windowRect)) {
|
|
2751
2954
|
return null;
|
|
2752
2955
|
}
|
|
2753
|
-
const
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2956
|
+
const clonedElement = cloneMeaningfulGenieElement(element, windowRect);
|
|
2957
|
+
if (!clonedElement) {
|
|
2958
|
+
return null;
|
|
2959
|
+
}
|
|
2960
|
+
const { clone, images } = clonedElement;
|
|
2758
2961
|
clone.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
2759
2962
|
clone.style.position = "relative";
|
|
2760
2963
|
clone.style.left = "0";
|
|
@@ -2765,15 +2968,23 @@ function prepareElementTextureCapture(element) {
|
|
|
2765
2968
|
clone.style.opacity = "1";
|
|
2766
2969
|
clone.style.visibility = "visible";
|
|
2767
2970
|
clone.style.pointerEvents = "none";
|
|
2768
|
-
return {
|
|
2971
|
+
return {
|
|
2972
|
+
clone,
|
|
2973
|
+
images,
|
|
2974
|
+
rect: windowRect
|
|
2975
|
+
};
|
|
2769
2976
|
}
|
|
2770
2977
|
async function renderPreparedElementTexture({
|
|
2771
2978
|
clone,
|
|
2772
|
-
|
|
2979
|
+
images,
|
|
2773
2980
|
rect
|
|
2774
2981
|
}) {
|
|
2775
|
-
await inlineCloneImageResources({
|
|
2776
|
-
|
|
2982
|
+
await inlineCloneImageResources({
|
|
2983
|
+
cloneRoot: clone,
|
|
2984
|
+
images
|
|
2985
|
+
});
|
|
2986
|
+
const svgTexture = createGenieSvgTexture(clone, rect);
|
|
2987
|
+
const image = await loadImageFromSvg(svgTexture);
|
|
2777
2988
|
const canvas = document.createElement("canvas");
|
|
2778
2989
|
canvas.width = Math.max(1, Math.round(rect.width * genieSnapshotScale));
|
|
2779
2990
|
canvas.height = Math.max(1, Math.round(rect.height * genieSnapshotScale));
|
|
@@ -2864,20 +3075,16 @@ async function captureWorkbenchNodePreviewImage(nodeID, options = {}) {
|
|
|
2864
3075
|
writeCachedWorkbenchNodePreviewImage(nodeID, previewImageUrl);
|
|
2865
3076
|
return previewImageUrl;
|
|
2866
3077
|
}
|
|
2867
|
-
async function
|
|
3078
|
+
async function captureProvidedWorkbenchNodePreviewImageForNode(node, input = {}) {
|
|
2868
3079
|
const previewImageUrl = await Promise.resolve(
|
|
2869
3080
|
input.captureNodePreviewImage?.(node) ?? null
|
|
2870
3081
|
).catch(() => null);
|
|
2871
|
-
if (previewImageUrl) {
|
|
2872
|
-
|
|
2873
|
-
persistWorkbenchNodePreviewImage(node, previewImageUrl, input);
|
|
2874
|
-
return previewImageUrl;
|
|
3082
|
+
if (!previewImageUrl) {
|
|
3083
|
+
return null;
|
|
2875
3084
|
}
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
persistWorkbenchNodePreviewImage(node, capturedPreviewImageUrl, input);
|
|
2880
|
-
return capturedPreviewImageUrl;
|
|
3085
|
+
writeCachedWorkbenchNodePreviewImage(node.id, previewImageUrl);
|
|
3086
|
+
persistWorkbenchNodePreviewImage(node, previewImageUrl, input);
|
|
3087
|
+
return previewImageUrl;
|
|
2881
3088
|
}
|
|
2882
3089
|
function persistWorkbenchNodePreviewImage(node, previewImageUrl, input) {
|
|
2883
3090
|
if (!previewImageUrl || !input.dockPreviewCache) {
|
|
@@ -2917,8 +3124,10 @@ function useWorkbenchGenieAnimation({
|
|
|
2917
3124
|
captureNodePreviewImage,
|
|
2918
3125
|
controller,
|
|
2919
3126
|
dockPreviewCache,
|
|
3127
|
+
minimizeAnimation = "genie",
|
|
2920
3128
|
resolveDockAnchorKey,
|
|
2921
|
-
resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2
|
|
3129
|
+
resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
|
|
3130
|
+
shouldCaptureNodePreviewImage
|
|
2922
3131
|
}) {
|
|
2923
3132
|
const dockAnchorElementsRef = useRef4(/* @__PURE__ */ new Map());
|
|
2924
3133
|
const canvasRef = useRef4(null);
|
|
@@ -2933,6 +3142,7 @@ function useWorkbenchGenieAnimation({
|
|
|
2933
3142
|
const [genieHiddenNodeIDs, setGenieHiddenNodeIDs] = useState4(
|
|
2934
3143
|
() => /* @__PURE__ */ new Set()
|
|
2935
3144
|
);
|
|
3145
|
+
const [pendingMinimizedNode, setPendingMinimizedNode] = useState4(null);
|
|
2936
3146
|
const registerDockAnchor = useCallback6(
|
|
2937
3147
|
(anchorKey, element) => {
|
|
2938
3148
|
if (element) {
|
|
@@ -3008,6 +3218,11 @@ function useWorkbenchGenieAnimation({
|
|
|
3008
3218
|
return next;
|
|
3009
3219
|
});
|
|
3010
3220
|
}, []);
|
|
3221
|
+
const clearPendingMinimizedNode = useCallback6((nodeID) => {
|
|
3222
|
+
setPendingMinimizedNode(
|
|
3223
|
+
(current) => current?.id === nodeID ? null : current
|
|
3224
|
+
);
|
|
3225
|
+
}, []);
|
|
3011
3226
|
const setupCanvas = useCallback6(() => {
|
|
3012
3227
|
const canvas = canvasRef.current;
|
|
3013
3228
|
if (!canvas) {
|
|
@@ -3120,10 +3335,102 @@ function useWorkbenchGenieAnimation({
|
|
|
3120
3335
|
},
|
|
3121
3336
|
[setupCanvas, stopAnimation]
|
|
3122
3337
|
);
|
|
3338
|
+
const runScaleWindowAnimation = useCallback6(
|
|
3339
|
+
({
|
|
3340
|
+
direction,
|
|
3341
|
+
dockRect,
|
|
3342
|
+
nodeElement,
|
|
3343
|
+
onCancel,
|
|
3344
|
+
onComplete,
|
|
3345
|
+
skipStop
|
|
3346
|
+
}) => {
|
|
3347
|
+
if (!skipStop) {
|
|
3348
|
+
stopAnimation();
|
|
3349
|
+
}
|
|
3350
|
+
const windowRect = viewportRectFromElement(nodeElement);
|
|
3351
|
+
if (!isUsableGenieRect(windowRect) || !isUsableGenieRect(dockRect)) {
|
|
3352
|
+
onComplete();
|
|
3353
|
+
return;
|
|
3354
|
+
}
|
|
3355
|
+
const generation = animationGenerationRef.current;
|
|
3356
|
+
const fromCenter = centerPointFromRect(windowRect);
|
|
3357
|
+
const toCenter = centerPointFromRect(dockRect);
|
|
3358
|
+
const targetScale = Math.max(
|
|
3359
|
+
0.04,
|
|
3360
|
+
Math.min(
|
|
3361
|
+
0.32,
|
|
3362
|
+
dockRect.width / Math.max(1, windowRect.width),
|
|
3363
|
+
dockRect.height / Math.max(1, windowRect.height)
|
|
3364
|
+
)
|
|
3365
|
+
);
|
|
3366
|
+
const previousPointerEvents = nodeElement.style.pointerEvents;
|
|
3367
|
+
const previousTransformOrigin = nodeElement.style.transformOrigin;
|
|
3368
|
+
const previousVisibility = nodeElement.style.visibility;
|
|
3369
|
+
const previousZIndex = nodeElement.style.zIndex;
|
|
3370
|
+
nodeElement.style.pointerEvents = "none";
|
|
3371
|
+
nodeElement.style.transformOrigin = "center center";
|
|
3372
|
+
nodeElement.style.visibility = "visible";
|
|
3373
|
+
nodeElement.style.zIndex = "var(--z-workbench-genie)";
|
|
3374
|
+
const dockTransform = `translate3d(${toCenter.x - fromCenter.x}px, ${toCenter.y - fromCenter.y}px, 0) scale(${targetScale})`;
|
|
3375
|
+
const windowTransform = "translate3d(0, 0, 0) scale(1)";
|
|
3376
|
+
const keyframes = direction === "open" ? [
|
|
3377
|
+
{
|
|
3378
|
+
opacity: 0,
|
|
3379
|
+
transform: dockTransform
|
|
3380
|
+
},
|
|
3381
|
+
{
|
|
3382
|
+
opacity: 1,
|
|
3383
|
+
transform: windowTransform
|
|
3384
|
+
}
|
|
3385
|
+
] : [
|
|
3386
|
+
{
|
|
3387
|
+
opacity: 1,
|
|
3388
|
+
transform: windowTransform
|
|
3389
|
+
},
|
|
3390
|
+
{
|
|
3391
|
+
opacity: 0,
|
|
3392
|
+
transform: dockTransform
|
|
3393
|
+
}
|
|
3394
|
+
];
|
|
3395
|
+
const animation = nodeElement.animate(keyframes, {
|
|
3396
|
+
duration: scaleMinimizeDurationMs,
|
|
3397
|
+
easing: "cubic-bezier(0.4, 0, 0.2, 1)",
|
|
3398
|
+
fill: "forwards"
|
|
3399
|
+
});
|
|
3400
|
+
const restoreElement = () => {
|
|
3401
|
+
animation.cancel();
|
|
3402
|
+
nodeElement.style.pointerEvents = previousPointerEvents;
|
|
3403
|
+
nodeElement.style.transformOrigin = previousTransformOrigin;
|
|
3404
|
+
nodeElement.style.visibility = previousVisibility;
|
|
3405
|
+
nodeElement.style.zIndex = previousZIndex;
|
|
3406
|
+
};
|
|
3407
|
+
animationCleanupRef.current = () => {
|
|
3408
|
+
restoreElement();
|
|
3409
|
+
onCancel();
|
|
3410
|
+
};
|
|
3411
|
+
animation.finished.then(() => {
|
|
3412
|
+
if (generation !== animationGenerationRef.current) {
|
|
3413
|
+
return;
|
|
3414
|
+
}
|
|
3415
|
+
animationCleanupRef.current = null;
|
|
3416
|
+
restoreElement();
|
|
3417
|
+
onComplete();
|
|
3418
|
+
}).catch(() => {
|
|
3419
|
+
if (generation !== animationGenerationRef.current) {
|
|
3420
|
+
return;
|
|
3421
|
+
}
|
|
3422
|
+
animationCleanupRef.current = null;
|
|
3423
|
+
restoreElement();
|
|
3424
|
+
onComplete();
|
|
3425
|
+
});
|
|
3426
|
+
},
|
|
3427
|
+
[stopAnimation]
|
|
3428
|
+
);
|
|
3123
3429
|
useEffect3(() => () => stopAnimation(false), [stopAnimation]);
|
|
3124
3430
|
const startOpenOrRestoreAnimation = useCallback6(
|
|
3125
3431
|
async (nodeID, anchorKey, generation, dockRectFallback) => {
|
|
3126
|
-
|
|
3432
|
+
const effectiveMinimizeAnimation = shouldReduceMotion() ? "off" : minimizeAnimation;
|
|
3433
|
+
if (effectiveMinimizeAnimation === "off") {
|
|
3127
3434
|
animationCleanupRef.current = null;
|
|
3128
3435
|
showNodeForGenie(nodeID);
|
|
3129
3436
|
return;
|
|
@@ -3135,6 +3442,32 @@ function useWorkbenchGenieAnimation({
|
|
|
3135
3442
|
const resolvedDockRect = resolveDockAnchorRect(anchorKey);
|
|
3136
3443
|
const dockRect = resolvedDockRect && isUsableGenieRect(resolvedDockRect) ? resolvedDockRect : dockRectFallback;
|
|
3137
3444
|
const nodeElement = resolveNodeElement(nodeID);
|
|
3445
|
+
if (effectiveMinimizeAnimation === "scale") {
|
|
3446
|
+
if (!dockRect || !nodeElement || !isUsableGenieRect(dockRect)) {
|
|
3447
|
+
animationCleanupRef.current = null;
|
|
3448
|
+
showNodeForGenie(nodeID);
|
|
3449
|
+
return;
|
|
3450
|
+
}
|
|
3451
|
+
flushSync(() => {
|
|
3452
|
+
showNodeForGenie(nodeID);
|
|
3453
|
+
});
|
|
3454
|
+
runScaleWindowAnimation({
|
|
3455
|
+
direction: "open",
|
|
3456
|
+
dockRect,
|
|
3457
|
+
nodeElement,
|
|
3458
|
+
onCancel: () => {
|
|
3459
|
+
flushSync(() => {
|
|
3460
|
+
showNodeForGenie(nodeID);
|
|
3461
|
+
});
|
|
3462
|
+
},
|
|
3463
|
+
onComplete: () => {
|
|
3464
|
+
flushSync(() => {
|
|
3465
|
+
showNodeForGenie(nodeID);
|
|
3466
|
+
});
|
|
3467
|
+
}
|
|
3468
|
+
});
|
|
3469
|
+
return;
|
|
3470
|
+
}
|
|
3138
3471
|
const captureTarget = nodeElement ? resolveWorkbenchCaptureElement(nodeElement) : null;
|
|
3139
3472
|
if (!dockRect || !nodeElement || !captureTarget || !isUsableGenieRect(dockRect)) {
|
|
3140
3473
|
animationCleanupRef.current = null;
|
|
@@ -3173,9 +3506,11 @@ function useWorkbenchGenieAnimation({
|
|
|
3173
3506
|
},
|
|
3174
3507
|
[
|
|
3175
3508
|
clearCanvas,
|
|
3509
|
+
minimizeAnimation,
|
|
3176
3510
|
resolveDockAnchorRect,
|
|
3177
3511
|
resolveNodeElement,
|
|
3178
3512
|
runGenieAnimation,
|
|
3513
|
+
runScaleWindowAnimation,
|
|
3179
3514
|
showNodeForGenie
|
|
3180
3515
|
]
|
|
3181
3516
|
);
|
|
@@ -3192,6 +3527,16 @@ function useWorkbenchGenieAnimation({
|
|
|
3192
3527
|
});
|
|
3193
3528
|
return;
|
|
3194
3529
|
}
|
|
3530
|
+
const effectiveMinimizeAnimation = shouldReduceMotion() ? "off" : minimizeAnimation;
|
|
3531
|
+
if (effectiveMinimizeAnimation === "off") {
|
|
3532
|
+
stopAnimation();
|
|
3533
|
+
flushSync(() => {
|
|
3534
|
+
showNodeForGenie(nodeID);
|
|
3535
|
+
});
|
|
3536
|
+
void Promise.resolve(launch()).catch(() => {
|
|
3537
|
+
});
|
|
3538
|
+
return;
|
|
3539
|
+
}
|
|
3195
3540
|
stopAnimation();
|
|
3196
3541
|
const dockRectFallback = resolveDockAnchorRect(anchorKey);
|
|
3197
3542
|
hideNodeForGenie(nodeID);
|
|
@@ -3216,6 +3561,7 @@ function useWorkbenchGenieAnimation({
|
|
|
3216
3561
|
clearCanvas,
|
|
3217
3562
|
controller,
|
|
3218
3563
|
hideNodeForGenie,
|
|
3564
|
+
minimizeAnimation,
|
|
3219
3565
|
resolveDockAnchorRect,
|
|
3220
3566
|
showNodeForGenie,
|
|
3221
3567
|
startOpenOrRestoreAnimation,
|
|
@@ -3230,23 +3576,137 @@ function useWorkbenchGenieAnimation({
|
|
|
3230
3576
|
return;
|
|
3231
3577
|
}
|
|
3232
3578
|
const runMinimize = minimize ?? (() => controller.commands.minimizeNode(nodeID));
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3579
|
+
const effectiveMinimizeAnimation = shouldReduceMotion() ? "off" : minimizeAnimation;
|
|
3580
|
+
const shouldCapturePreview = shouldCaptureNodePreviewImage?.(target) ?? true;
|
|
3581
|
+
if (effectiveMinimizeAnimation === "off") {
|
|
3582
|
+
stopAnimation();
|
|
3583
|
+
let frameID = null;
|
|
3584
|
+
let timerID = null;
|
|
3585
|
+
let minimizeCommitted2 = false;
|
|
3586
|
+
const commitMinimize2 = () => {
|
|
3587
|
+
if (minimizeCommitted2) {
|
|
3588
|
+
return;
|
|
3589
|
+
}
|
|
3590
|
+
minimizeCommitted2 = true;
|
|
3591
|
+
if (frameID !== null) {
|
|
3592
|
+
window.cancelAnimationFrame(frameID);
|
|
3593
|
+
frameID = null;
|
|
3594
|
+
}
|
|
3595
|
+
if (timerID !== null) {
|
|
3596
|
+
clearTimeout(timerID);
|
|
3597
|
+
timerID = null;
|
|
3598
|
+
}
|
|
3599
|
+
animationCleanupRef.current = null;
|
|
3600
|
+
flushSync(() => {
|
|
3601
|
+
clearPendingMinimizedNode(nodeID);
|
|
3602
|
+
showNodeForGenie(nodeID);
|
|
3603
|
+
runMinimize();
|
|
3604
|
+
});
|
|
3605
|
+
scheduleReleaseMinimizedDockEnterAnimation(nodeID);
|
|
3606
|
+
};
|
|
3607
|
+
animationCleanupRef.current = () => {
|
|
3608
|
+
releaseMinimizedDockEnterAnimation(nodeID);
|
|
3609
|
+
commitMinimize2();
|
|
3610
|
+
};
|
|
3611
|
+
registerMinimizedDockEnterAnimation(nodeID);
|
|
3612
|
+
flushSync(() => {
|
|
3613
|
+
hideNodeForGenie(nodeID);
|
|
3614
|
+
setPendingMinimizedNode({
|
|
3615
|
+
...target,
|
|
3616
|
+
isMinimized: true,
|
|
3617
|
+
minimizedAtUnixMs: Date.now()
|
|
3618
|
+
});
|
|
3619
|
+
});
|
|
3620
|
+
if (shouldCapturePreview) {
|
|
3621
|
+
void captureProvidedWorkbenchNodePreviewImageForNode(target, {
|
|
3622
|
+
captureNodePreviewImage,
|
|
3623
|
+
dockPreviewCache,
|
|
3624
|
+
resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2
|
|
3625
|
+
});
|
|
3626
|
+
}
|
|
3627
|
+
frameID = window.requestAnimationFrame(() => {
|
|
3628
|
+
frameID = null;
|
|
3629
|
+
timerID = setTimeout(commitMinimize2, 0);
|
|
3630
|
+
});
|
|
3631
|
+
return;
|
|
3632
|
+
}
|
|
3633
|
+
if (effectiveMinimizeAnimation === "scale") {
|
|
3634
|
+
stopAnimation();
|
|
3635
|
+
const generation2 = animationGenerationRef.current;
|
|
3636
|
+
const nodeElement2 = resolveNodeElement(nodeID);
|
|
3637
|
+
if (!nodeElement2) {
|
|
3638
|
+
runMinimize();
|
|
3639
|
+
return;
|
|
3640
|
+
}
|
|
3641
|
+
const wasFocusedForCapture2 = shouldCapturePreview && isFocusedWorkbenchNode(controller, nodeID);
|
|
3642
|
+
if (shouldCapturePreview && !wasFocusedForCapture2) {
|
|
3239
3643
|
flushSync(() => {
|
|
3240
3644
|
controller.commands.focusNode(nodeID);
|
|
3241
3645
|
});
|
|
3242
3646
|
await waitForNextAnimationFrame();
|
|
3647
|
+
if (generation2 !== animationGenerationRef.current) {
|
|
3648
|
+
return;
|
|
3649
|
+
}
|
|
3243
3650
|
}
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3651
|
+
if (shouldCapturePreview) {
|
|
3652
|
+
void captureProvidedWorkbenchNodePreviewImageForNode(target, {
|
|
3653
|
+
captureNodePreviewImage,
|
|
3654
|
+
dockPreviewCache,
|
|
3655
|
+
resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2
|
|
3656
|
+
});
|
|
3657
|
+
}
|
|
3658
|
+
let minimizeCommitted2 = false;
|
|
3659
|
+
const commitMinimize2 = () => {
|
|
3660
|
+
if (minimizeCommitted2) {
|
|
3661
|
+
return;
|
|
3662
|
+
}
|
|
3663
|
+
minimizeCommitted2 = true;
|
|
3664
|
+
runMinimize();
|
|
3665
|
+
};
|
|
3666
|
+
const cleanupPendingMinimize = () => {
|
|
3667
|
+
releaseMinimizedDockEnterAnimation(nodeID);
|
|
3668
|
+
flushSync(() => {
|
|
3669
|
+
clearPendingMinimizedNode(nodeID);
|
|
3670
|
+
commitMinimize2();
|
|
3671
|
+
});
|
|
3672
|
+
};
|
|
3673
|
+
const pendingMinimizedNode3 = {
|
|
3674
|
+
...target,
|
|
3675
|
+
isMinimized: true,
|
|
3676
|
+
minimizedAtUnixMs: Date.now()
|
|
3677
|
+
};
|
|
3678
|
+
registerMinimizedDockEnterAnimation(nodeID);
|
|
3679
|
+
flushSync(() => {
|
|
3680
|
+
setPendingMinimizedNode(pendingMinimizedNode3);
|
|
3681
|
+
});
|
|
3682
|
+
animationCleanupRef.current = cleanupPendingMinimize;
|
|
3683
|
+
await waitForNextAnimationFrame();
|
|
3684
|
+
if (generation2 !== animationGenerationRef.current) {
|
|
3685
|
+
return;
|
|
3686
|
+
}
|
|
3687
|
+
const anchorKey2 = resolveAnchorKeyForNode(pendingMinimizedNode3);
|
|
3688
|
+
const dockRect2 = resolveDockAnchorRect(anchorKey2);
|
|
3689
|
+
if (!nodeElement2.isConnected || !dockRect2 || !isUsableGenieRect(dockRect2)) {
|
|
3690
|
+
cleanupPendingMinimize();
|
|
3691
|
+
return;
|
|
3692
|
+
}
|
|
3693
|
+
runScaleWindowAnimation({
|
|
3694
|
+
direction: "minimize",
|
|
3695
|
+
dockRect: dockRect2,
|
|
3696
|
+
nodeElement: nodeElement2,
|
|
3697
|
+
onCancel: () => {
|
|
3698
|
+
cleanupPendingMinimize();
|
|
3699
|
+
},
|
|
3700
|
+
onComplete: () => {
|
|
3701
|
+
animationCleanupRef.current = null;
|
|
3702
|
+
flushSync(() => {
|
|
3703
|
+
clearPendingMinimizedNode(nodeID);
|
|
3704
|
+
commitMinimize2();
|
|
3705
|
+
});
|
|
3706
|
+
scheduleReleaseMinimizedDockEnterAnimation(nodeID);
|
|
3707
|
+
},
|
|
3708
|
+
skipStop: true
|
|
3248
3709
|
});
|
|
3249
|
-
runMinimize();
|
|
3250
3710
|
return;
|
|
3251
3711
|
}
|
|
3252
3712
|
stopAnimation();
|
|
@@ -3309,46 +3769,57 @@ function useWorkbenchGenieAnimation({
|
|
|
3309
3769
|
resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2
|
|
3310
3770
|
});
|
|
3311
3771
|
}
|
|
3312
|
-
|
|
3772
|
+
let minimizeCommitted = false;
|
|
3773
|
+
const commitMinimize = () => {
|
|
3774
|
+
if (minimizeCommitted) {
|
|
3775
|
+
return;
|
|
3776
|
+
}
|
|
3777
|
+
minimizeCommitted = true;
|
|
3778
|
+
runMinimize();
|
|
3779
|
+
};
|
|
3780
|
+
const pendingMinimizedNode2 = {
|
|
3781
|
+
...target,
|
|
3782
|
+
isMinimized: true,
|
|
3783
|
+
minimizedAtUnixMs: Date.now()
|
|
3784
|
+
};
|
|
3785
|
+
const cleanupPendingGenieMinimize = () => {
|
|
3786
|
+
releaseMinimizedDockEnterAnimation(nodeID);
|
|
3313
3787
|
flushSync(() => {
|
|
3788
|
+
clearPendingMinimizedNode(nodeID);
|
|
3314
3789
|
showNodeForGenie(nodeID);
|
|
3790
|
+
commitMinimize();
|
|
3315
3791
|
});
|
|
3316
3792
|
clearCanvas();
|
|
3317
3793
|
};
|
|
3318
|
-
animationCleanupRef.current =
|
|
3794
|
+
animationCleanupRef.current = cleanupPendingGenieMinimize;
|
|
3319
3795
|
registerMinimizedDockEnterAnimation(nodeID);
|
|
3320
3796
|
flushSync(() => {
|
|
3797
|
+
setPendingMinimizedNode(pendingMinimizedNode2);
|
|
3321
3798
|
hideNodeForGenie(nodeID);
|
|
3322
|
-
runMinimize();
|
|
3323
3799
|
});
|
|
3324
3800
|
await waitForNextAnimationFrame();
|
|
3325
3801
|
if (generation !== animationGenerationRef.current) {
|
|
3326
|
-
releaseMinimizedDockEnterAnimation(nodeID);
|
|
3327
3802
|
return;
|
|
3328
3803
|
}
|
|
3329
|
-
const
|
|
3330
|
-
const anchorKey = resolveAnchorKeyForNode(minimizedTarget);
|
|
3804
|
+
const anchorKey = resolveAnchorKeyForNode(pendingMinimizedNode2);
|
|
3331
3805
|
const dockRect = resolveDockAnchorRect(anchorKey);
|
|
3332
3806
|
if (!dockRect || !isUsableGenieRect(dockRect)) {
|
|
3333
|
-
releaseMinimizedDockEnterAnimation(nodeID);
|
|
3334
3807
|
animationCleanupRef.current = null;
|
|
3335
|
-
|
|
3808
|
+
cleanupPendingGenieMinimize();
|
|
3336
3809
|
return;
|
|
3337
3810
|
}
|
|
3338
3811
|
runGenieAnimation({
|
|
3339
3812
|
direction: "minimize",
|
|
3340
3813
|
dockRect,
|
|
3341
3814
|
onCancel: () => {
|
|
3342
|
-
|
|
3343
|
-
flushSync(() => {
|
|
3344
|
-
showNodeForGenie(nodeID);
|
|
3345
|
-
});
|
|
3346
|
-
clearCanvas();
|
|
3815
|
+
cleanupPendingGenieMinimize();
|
|
3347
3816
|
},
|
|
3348
3817
|
onComplete: () => {
|
|
3349
3818
|
scheduleReleaseMinimizedDockEnterAnimation(nodeID);
|
|
3350
3819
|
flushSync(() => {
|
|
3820
|
+
clearPendingMinimizedNode(nodeID);
|
|
3351
3821
|
showNodeForGenie(nodeID);
|
|
3822
|
+
commitMinimize();
|
|
3352
3823
|
});
|
|
3353
3824
|
clearCanvas();
|
|
3354
3825
|
},
|
|
@@ -3361,8 +3832,10 @@ function useWorkbenchGenieAnimation({
|
|
|
3361
3832
|
clearCanvas,
|
|
3362
3833
|
controller,
|
|
3363
3834
|
captureNodePreviewImage,
|
|
3835
|
+
clearPendingMinimizedNode,
|
|
3364
3836
|
dockPreviewCache,
|
|
3365
3837
|
hideNodeForGenie,
|
|
3838
|
+
minimizeAnimation,
|
|
3366
3839
|
registerMinimizedDockEnterAnimation,
|
|
3367
3840
|
releaseMinimizedDockEnterAnimation,
|
|
3368
3841
|
resolveAnchorKeyForNode,
|
|
@@ -3370,7 +3843,9 @@ function useWorkbenchGenieAnimation({
|
|
|
3370
3843
|
resolveDockAnchorRect,
|
|
3371
3844
|
resolveNodeElement,
|
|
3372
3845
|
runGenieAnimation,
|
|
3846
|
+
runScaleWindowAnimation,
|
|
3373
3847
|
scheduleReleaseMinimizedDockEnterAnimation,
|
|
3848
|
+
shouldCaptureNodePreviewImage,
|
|
3374
3849
|
setupCanvas,
|
|
3375
3850
|
showNodeForGenie,
|
|
3376
3851
|
stopAnimation
|
|
@@ -3403,8 +3878,13 @@ function useWorkbenchGenieAnimation({
|
|
|
3403
3878
|
(nodeID) => genieHiddenNodeIDs.has(nodeID),
|
|
3404
3879
|
[genieHiddenNodeIDs]
|
|
3405
3880
|
),
|
|
3881
|
+
isPendingMinimizedDockNode: useCallback6(
|
|
3882
|
+
(nodeID) => pendingMinimizedNode?.id === nodeID,
|
|
3883
|
+
[pendingMinimizedNode]
|
|
3884
|
+
),
|
|
3406
3885
|
launchNodeFromAnchor,
|
|
3407
3886
|
minimizeNodeToAnchor,
|
|
3887
|
+
pendingMinimizedNode,
|
|
3408
3888
|
registerDockAnchor,
|
|
3409
3889
|
shouldAnimateMinimizedDockEnter
|
|
3410
3890
|
};
|
|
@@ -3421,6 +3901,7 @@ function WorkbenchSurface({
|
|
|
3421
3901
|
interactive,
|
|
3422
3902
|
layoutConstraints,
|
|
3423
3903
|
missionControlPhase,
|
|
3904
|
+
minimizeAnimation,
|
|
3424
3905
|
presentation,
|
|
3425
3906
|
renderBackdrop,
|
|
3426
3907
|
renderBottomChrome,
|
|
@@ -3435,6 +3916,7 @@ function WorkbenchSurface({
|
|
|
3435
3916
|
resolveDockAnchorKey,
|
|
3436
3917
|
resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
|
|
3437
3918
|
shortcutsEnabled,
|
|
3919
|
+
shouldCaptureNodePreviewImage,
|
|
3438
3920
|
wallpaper,
|
|
3439
3921
|
windowChromeMode,
|
|
3440
3922
|
windowChromeI18n
|
|
@@ -3449,6 +3931,7 @@ function WorkbenchSurface({
|
|
|
3449
3931
|
interactive,
|
|
3450
3932
|
layoutConstraints,
|
|
3451
3933
|
missionControlPhase,
|
|
3934
|
+
minimizeAnimation,
|
|
3452
3935
|
presentation,
|
|
3453
3936
|
renderBackdrop,
|
|
3454
3937
|
renderBottomChrome,
|
|
@@ -3463,6 +3946,7 @@ function WorkbenchSurface({
|
|
|
3463
3946
|
resolveDockAnchorKey,
|
|
3464
3947
|
resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
|
|
3465
3948
|
shortcutsEnabled,
|
|
3949
|
+
shouldCaptureNodePreviewImage,
|
|
3466
3950
|
wallpaper,
|
|
3467
3951
|
windowChromeMode,
|
|
3468
3952
|
windowChromeI18n
|
|
@@ -3477,6 +3961,7 @@ function WorkbenchSurfaceInner({
|
|
|
3477
3961
|
interactive = true,
|
|
3478
3962
|
layoutConstraints,
|
|
3479
3963
|
missionControlPhase,
|
|
3964
|
+
minimizeAnimation,
|
|
3480
3965
|
presentation,
|
|
3481
3966
|
renderBackdrop,
|
|
3482
3967
|
renderBottomChrome,
|
|
@@ -3491,6 +3976,7 @@ function WorkbenchSurfaceInner({
|
|
|
3491
3976
|
resolveDockAnchorKey,
|
|
3492
3977
|
resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
|
|
3493
3978
|
shortcutsEnabled,
|
|
3979
|
+
shouldCaptureNodePreviewImage,
|
|
3494
3980
|
wallpaper,
|
|
3495
3981
|
windowChromeMode,
|
|
3496
3982
|
windowChromeI18n
|
|
@@ -3507,8 +3993,10 @@ function WorkbenchSurfaceInner({
|
|
|
3507
3993
|
captureNodePreviewImage,
|
|
3508
3994
|
controller,
|
|
3509
3995
|
dockPreviewCache,
|
|
3996
|
+
minimizeAnimation,
|
|
3510
3997
|
resolveDockAnchorKey,
|
|
3511
|
-
resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2
|
|
3998
|
+
resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
|
|
3999
|
+
shouldCaptureNodePreviewImage
|
|
3512
4000
|
});
|
|
3513
4001
|
useWorkbenchShortcuts((shortcutsEnabled ?? true) && interactive);
|
|
3514
4002
|
useEffect4(() => {
|
|
@@ -4769,6 +5257,11 @@ var WorkbenchHostSessionController = class {
|
|
|
4769
5257
|
this.restoreAndFocusNode(nodeId);
|
|
4770
5258
|
});
|
|
4771
5259
|
}
|
|
5260
|
+
minimizeNode(nodeId) {
|
|
5261
|
+
this.runWhenReady(this.loadGeneration, () => {
|
|
5262
|
+
this.controller.commands.minimizeNode(nodeId);
|
|
5263
|
+
});
|
|
5264
|
+
}
|
|
4772
5265
|
exitFullscreenNode(nodeId) {
|
|
4773
5266
|
this.runWhenReady(this.loadGeneration, () => {
|
|
4774
5267
|
this.controller.commands.exitFullscreen(nodeId);
|
|
@@ -6244,7 +6737,7 @@ function resolveWorkbenchMinimizedDockAnchorKeyForNode(input) {
|
|
|
6244
6737
|
}
|
|
6245
6738
|
function isWorkbenchMinimizedDockEligibleNode(input) {
|
|
6246
6739
|
const definition = input.nodeDefinitions.get(input.node.data.typeId);
|
|
6247
|
-
return definition?.window?.minimizedDock
|
|
6740
|
+
return definition?.window?.minimizedDock !== void 0;
|
|
6248
6741
|
}
|
|
6249
6742
|
function orderWorkbenchMinimizedDockNodes(input) {
|
|
6250
6743
|
return input.nodes.map((node, index) => ({ index, node })).filter(
|
|
@@ -6360,7 +6853,18 @@ import {
|
|
|
6360
6853
|
useState as useState7
|
|
6361
6854
|
} from "react";
|
|
6362
6855
|
import { createPortal as createPortal2 } from "react-dom";
|
|
6363
|
-
import {
|
|
6856
|
+
import {
|
|
6857
|
+
Button as Button3,
|
|
6858
|
+
CheckIcon,
|
|
6859
|
+
CloseIcon,
|
|
6860
|
+
FileCreateIcon,
|
|
6861
|
+
MaximizeIcon as MaximizeIcon2,
|
|
6862
|
+
MinimizeIcon,
|
|
6863
|
+
OverviewLayoutIcon,
|
|
6864
|
+
PinFilledIcon,
|
|
6865
|
+
PinIcon,
|
|
6866
|
+
cn
|
|
6867
|
+
} from "@tutti-os/ui-system";
|
|
6364
6868
|
|
|
6365
6869
|
// src/host/minimizedStackScroll.ts
|
|
6366
6870
|
var minimizedStackViewportMarginPx = 56;
|
|
@@ -6492,7 +6996,7 @@ function resolveMinimizedStackTrackTranslateXPx(input) {
|
|
|
6492
6996
|
}
|
|
6493
6997
|
|
|
6494
6998
|
// src/host/WorkbenchHostDockPopup.tsx
|
|
6495
|
-
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
6999
|
+
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
6496
7000
|
var dockPopupCardWidthPx = 165;
|
|
6497
7001
|
var dockPopupGridGapPx = 8;
|
|
6498
7002
|
var dockPopupPanelPaddingInlinePx = 12;
|
|
@@ -6557,9 +7061,14 @@ function writeDockPopupPreviewImage(memoryKey, preview, revision) {
|
|
|
6557
7061
|
}
|
|
6558
7062
|
function WorkbenchHostDockPopup({
|
|
6559
7063
|
anchorRect,
|
|
7064
|
+
canEnterFullscreen,
|
|
7065
|
+
canShowAllWindows,
|
|
6560
7066
|
capturePreview,
|
|
6561
7067
|
debugDiagnostics,
|
|
7068
|
+
dockRetention,
|
|
6562
7069
|
dockPreviewCache,
|
|
7070
|
+
fullscreenLabel,
|
|
7071
|
+
hideLabel,
|
|
6563
7072
|
items,
|
|
6564
7073
|
label,
|
|
6565
7074
|
labelMode,
|
|
@@ -6568,15 +7077,25 @@ function WorkbenchHostDockPopup({
|
|
|
6568
7077
|
onClose,
|
|
6569
7078
|
onCloseNode,
|
|
6570
7079
|
onCreateNew,
|
|
7080
|
+
onEnterFullscreen,
|
|
7081
|
+
onHide,
|
|
7082
|
+
onRunDockRetentionAction,
|
|
6571
7083
|
onSelectNode,
|
|
7084
|
+
onShowAllWindows,
|
|
7085
|
+
openLabel,
|
|
7086
|
+
onQuit,
|
|
6572
7087
|
placement = "bottom",
|
|
7088
|
+
quitLabel,
|
|
6573
7089
|
resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
|
|
7090
|
+
showAllWindowsLabel,
|
|
6574
7091
|
showCreateNew,
|
|
7092
|
+
showOpen,
|
|
6575
7093
|
variant
|
|
6576
7094
|
}) {
|
|
6577
7095
|
const resolvedLabelMode = labelMode ?? "hover-overlay";
|
|
6578
7096
|
const resolvedVariant = variant ?? "default";
|
|
6579
7097
|
const isMinimizedStack = resolvedVariant === "minimized-stack";
|
|
7098
|
+
const isContextMenu = resolvedVariant === "context-menu";
|
|
6580
7099
|
const createCardCount = showCreateNew === false ? 0 : 1;
|
|
6581
7100
|
const cardElementsRef = useRef7(/* @__PURE__ */ new Map());
|
|
6582
7101
|
const cardRefCallbacksRef = useRef7(
|
|
@@ -6587,8 +7106,8 @@ function WorkbenchHostDockPopup({
|
|
|
6587
7106
|
const [pointer, setPointer] = useState7(null);
|
|
6588
7107
|
const [minimizedStackScrollOffset, setMinimizedStackScrollOffset] = useState7(0);
|
|
6589
7108
|
const [capturedPreviewByMemoryKey, setCapturedPreviewByMemoryKey] = useState7({});
|
|
6590
|
-
const columnCount = Math.min(Math.max(items.length + createCardCount, 1), 3);
|
|
6591
|
-
const popupWidthPx = columnCount * dockPopupCardWidthPx + Math.max(0, columnCount - 1) * dockPopupGridGapPx + dockPopupPanelPaddingInlinePx * 2 + dockPopupPanelBorderInlinePx;
|
|
7109
|
+
const columnCount = isContextMenu ? 1 : Math.min(Math.max(items.length + createCardCount, 1), 3);
|
|
7110
|
+
const popupWidthPx = isContextMenu ? 268 : columnCount * dockPopupCardWidthPx + Math.max(0, columnCount - 1) * dockPopupGridGapPx + dockPopupPanelPaddingInlinePx * 2 + dockPopupPanelBorderInlinePx;
|
|
6592
7111
|
const popupCenterY = anchorRect.top + anchorRect.height / 2;
|
|
6593
7112
|
const isLeftMinimizedStack = placement === "left" && isMinimizedStack;
|
|
6594
7113
|
const minimizedStackTrackHeightPx = resolveMinimizedStackTrackHeightPx(
|
|
@@ -6766,7 +7285,7 @@ function WorkbenchHostDockPopup({
|
|
|
6766
7285
|
return () => viewport.removeEventListener("wheel", handleWheel);
|
|
6767
7286
|
}, [isMinimizedStack, minimizedStackMaxScrollOffset]);
|
|
6768
7287
|
useEffect8(() => {
|
|
6769
|
-
if (!capturePreview) {
|
|
7288
|
+
if (!capturePreview || isContextMenu) {
|
|
6770
7289
|
return;
|
|
6771
7290
|
}
|
|
6772
7291
|
let cancelled = false;
|
|
@@ -6977,6 +7496,7 @@ function WorkbenchHostDockPopup({
|
|
|
6977
7496
|
}, [
|
|
6978
7497
|
capturePreview,
|
|
6979
7498
|
dockPreviewCache,
|
|
7499
|
+
isContextMenu,
|
|
6980
7500
|
items,
|
|
6981
7501
|
previewCaptureKey,
|
|
6982
7502
|
resolveDockPreviewCacheKey2
|
|
@@ -6990,12 +7510,13 @@ function WorkbenchHostDockPopup({
|
|
|
6990
7510
|
"data-desktop-dock-popup-root": "true",
|
|
6991
7511
|
"data-popup-variant": resolvedVariant,
|
|
6992
7512
|
style: popupStyle,
|
|
6993
|
-
children: /* @__PURE__ */
|
|
7513
|
+
children: /* @__PURE__ */ jsx9(
|
|
6994
7514
|
"div",
|
|
6995
7515
|
{
|
|
6996
7516
|
"aria-label": label,
|
|
6997
7517
|
className: cn(
|
|
6998
|
-
"desktop-dock-popup relative origin-bottom rounded-lg border border-[var(--border-1)] bg-background-fronted
|
|
7518
|
+
"desktop-dock-popup relative origin-bottom rounded-lg border border-[var(--border-1)] bg-background-fronted text-[var(--text-primary)] shadow-panel motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-95 motion-safe:slide-in-from-bottom-2 motion-safe:duration-[175ms] motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:animate-none",
|
|
7519
|
+
isContextMenu ? "p-1" : "p-3",
|
|
6999
7520
|
isLeftMinimizedStack ? "w-full min-w-0 max-w-none" : "w-[min(var(--desktop-dock-popup-width,366px),calc(100vw-32px))]"
|
|
7000
7521
|
),
|
|
7001
7522
|
"data-desktop-dock-popup-panel": "true",
|
|
@@ -7005,8 +7526,31 @@ function WorkbenchHostDockPopup({
|
|
|
7005
7526
|
onPointerLeave: isMinimizedStack ? () => setPointer(null) : void 0,
|
|
7006
7527
|
role: "dialog",
|
|
7007
7528
|
style: panelStyle,
|
|
7008
|
-
children:
|
|
7009
|
-
|
|
7529
|
+
children: isContextMenu ? /* @__PURE__ */ jsx9(
|
|
7530
|
+
WorkbenchHostDockContextMenu,
|
|
7531
|
+
{
|
|
7532
|
+
canCreateNew: showCreateNew !== false,
|
|
7533
|
+
canEnterFullscreen: canEnterFullscreen === true,
|
|
7534
|
+
canShowAllWindows: canShowAllWindows === true,
|
|
7535
|
+
dockRetention,
|
|
7536
|
+
fullscreenLabel,
|
|
7537
|
+
hideLabel,
|
|
7538
|
+
items,
|
|
7539
|
+
newWindowLabel,
|
|
7540
|
+
onCreateNew,
|
|
7541
|
+
onEnterFullscreen,
|
|
7542
|
+
onHide,
|
|
7543
|
+
onQuit,
|
|
7544
|
+
onRunDockRetentionAction,
|
|
7545
|
+
onSelectNode,
|
|
7546
|
+
onShowAllWindows,
|
|
7547
|
+
openLabel,
|
|
7548
|
+
quitLabel,
|
|
7549
|
+
showAllWindowsLabel,
|
|
7550
|
+
showOpen: showOpen === true
|
|
7551
|
+
}
|
|
7552
|
+
) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
7553
|
+
/* @__PURE__ */ jsx9("div", { className: "mb-2.5 flex items-center justify-between", children: /* @__PURE__ */ jsx9("span", { className: "min-w-0 truncate text-sm font-semibold", children: label }) }),
|
|
7010
7554
|
isMinimizedStack ? /* @__PURE__ */ jsx9(
|
|
7011
7555
|
"div",
|
|
7012
7556
|
{
|
|
@@ -7111,7 +7655,7 @@ function WorkbenchHostDockPopup({
|
|
|
7111
7655
|
}
|
|
7112
7656
|
) : null
|
|
7113
7657
|
] })
|
|
7114
|
-
]
|
|
7658
|
+
] })
|
|
7115
7659
|
}
|
|
7116
7660
|
)
|
|
7117
7661
|
}
|
|
@@ -7121,6 +7665,172 @@ function WorkbenchHostDockPopup({
|
|
|
7121
7665
|
}
|
|
7122
7666
|
return createPortal2(content, document.body);
|
|
7123
7667
|
}
|
|
7668
|
+
function WorkbenchHostDockContextMenu({
|
|
7669
|
+
canCreateNew,
|
|
7670
|
+
canEnterFullscreen,
|
|
7671
|
+
canShowAllWindows,
|
|
7672
|
+
dockRetention,
|
|
7673
|
+
fullscreenLabel,
|
|
7674
|
+
hideLabel,
|
|
7675
|
+
items,
|
|
7676
|
+
newWindowLabel,
|
|
7677
|
+
onCreateNew,
|
|
7678
|
+
onEnterFullscreen,
|
|
7679
|
+
onHide,
|
|
7680
|
+
onQuit,
|
|
7681
|
+
onRunDockRetentionAction,
|
|
7682
|
+
onSelectNode,
|
|
7683
|
+
onShowAllWindows,
|
|
7684
|
+
openLabel,
|
|
7685
|
+
quitLabel,
|
|
7686
|
+
showAllWindowsLabel,
|
|
7687
|
+
showOpen
|
|
7688
|
+
}) {
|
|
7689
|
+
const hasOpenWindows = items.length > 0;
|
|
7690
|
+
const hasNewWindowCommand = hasOpenWindows && canCreateNew;
|
|
7691
|
+
const hasOpenCommand = !hasOpenWindows;
|
|
7692
|
+
const hasDockActionGroup = Boolean(dockRetention) || hasNewWindowCommand || hasOpenCommand;
|
|
7693
|
+
const hasWindowActionGroup = hasOpenWindows;
|
|
7694
|
+
return /* @__PURE__ */ jsxs5(
|
|
7695
|
+
"div",
|
|
7696
|
+
{
|
|
7697
|
+
className: "flex min-w-0 flex-col gap-1",
|
|
7698
|
+
"data-desktop-dock-context-menu": "true",
|
|
7699
|
+
role: "menu",
|
|
7700
|
+
children: [
|
|
7701
|
+
hasOpenWindows ? /* @__PURE__ */ jsx9(Fragment3, { children: /* @__PURE__ */ jsx9("div", { className: "max-h-48 min-w-0 overflow-auto overscroll-contain", children: items.map((item) => /* @__PURE__ */ jsx9(
|
|
7702
|
+
WorkbenchHostDockContextMenuItem,
|
|
7703
|
+
{
|
|
7704
|
+
checked: !item.isMinimized,
|
|
7705
|
+
label: item.title?.trim() || item.node.title,
|
|
7706
|
+
onSelect: () => onSelectNode(item.node.id)
|
|
7707
|
+
},
|
|
7708
|
+
item.node.id
|
|
7709
|
+
)) }) }) : null,
|
|
7710
|
+
hasOpenWindows && (hasDockActionGroup || hasWindowActionGroup) ? /* @__PURE__ */ jsx9(WorkbenchHostDockContextMenuSeparator, {}) : null,
|
|
7711
|
+
dockRetention ? /* @__PURE__ */ jsx9(
|
|
7712
|
+
WorkbenchHostDockContextMenuItem,
|
|
7713
|
+
{
|
|
7714
|
+
checked: dockRetention.checked,
|
|
7715
|
+
checkedIcon: /* @__PURE__ */ jsx9(
|
|
7716
|
+
PinFilledIcon,
|
|
7717
|
+
{
|
|
7718
|
+
"aria-hidden": "true",
|
|
7719
|
+
className: "size-4 text-[var(--tutti-purple)]"
|
|
7720
|
+
}
|
|
7721
|
+
),
|
|
7722
|
+
disabled: dockRetention.disabled,
|
|
7723
|
+
icon: /* @__PURE__ */ jsx9(PinIcon, { "aria-hidden": "true", className: "size-4" }),
|
|
7724
|
+
label: dockRetention.pendingLabel ?? dockRetention.label,
|
|
7725
|
+
onSelect: onRunDockRetentionAction
|
|
7726
|
+
}
|
|
7727
|
+
) : null,
|
|
7728
|
+
hasNewWindowCommand ? /* @__PURE__ */ jsx9(
|
|
7729
|
+
WorkbenchHostDockContextMenuItem,
|
|
7730
|
+
{
|
|
7731
|
+
icon: /* @__PURE__ */ jsx9(FileCreateIcon, { "aria-hidden": "true", className: "size-4" }),
|
|
7732
|
+
label: newWindowLabel,
|
|
7733
|
+
onSelect: onCreateNew
|
|
7734
|
+
}
|
|
7735
|
+
) : null,
|
|
7736
|
+
hasOpenCommand ? /* @__PURE__ */ jsx9(
|
|
7737
|
+
WorkbenchHostDockContextMenuItem,
|
|
7738
|
+
{
|
|
7739
|
+
disabled: !showOpen,
|
|
7740
|
+
icon: /* @__PURE__ */ jsx9(FileCreateIcon, { "aria-hidden": "true", className: "size-4" }),
|
|
7741
|
+
label: openLabel,
|
|
7742
|
+
onSelect: onCreateNew
|
|
7743
|
+
}
|
|
7744
|
+
) : null,
|
|
7745
|
+
hasOpenWindows ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
7746
|
+
hasDockActionGroup ? /* @__PURE__ */ jsx9(WorkbenchHostDockContextMenuSeparator, {}) : null,
|
|
7747
|
+
canShowAllWindows && onShowAllWindows ? /* @__PURE__ */ jsx9(
|
|
7748
|
+
WorkbenchHostDockContextMenuItem,
|
|
7749
|
+
{
|
|
7750
|
+
icon: /* @__PURE__ */ jsx9(OverviewLayoutIcon, { "aria-hidden": "true", className: "size-4" }),
|
|
7751
|
+
label: showAllWindowsLabel,
|
|
7752
|
+
onSelect: onShowAllWindows
|
|
7753
|
+
}
|
|
7754
|
+
) : null,
|
|
7755
|
+
/* @__PURE__ */ jsx9(
|
|
7756
|
+
WorkbenchHostDockContextMenuItem,
|
|
7757
|
+
{
|
|
7758
|
+
disabled: !canEnterFullscreen || !onEnterFullscreen,
|
|
7759
|
+
icon: /* @__PURE__ */ jsx9(MaximizeIcon2, { "aria-hidden": "true", className: "size-4" }),
|
|
7760
|
+
label: fullscreenLabel,
|
|
7761
|
+
onSelect: onEnterFullscreen
|
|
7762
|
+
}
|
|
7763
|
+
),
|
|
7764
|
+
/* @__PURE__ */ jsx9(
|
|
7765
|
+
WorkbenchHostDockContextMenuItem,
|
|
7766
|
+
{
|
|
7767
|
+
disabled: !onHide,
|
|
7768
|
+
icon: /* @__PURE__ */ jsx9(MinimizeIcon, { "aria-hidden": "true", className: "size-4" }),
|
|
7769
|
+
label: hideLabel,
|
|
7770
|
+
onSelect: onHide
|
|
7771
|
+
}
|
|
7772
|
+
),
|
|
7773
|
+
/* @__PURE__ */ jsx9(
|
|
7774
|
+
WorkbenchHostDockContextMenuItem,
|
|
7775
|
+
{
|
|
7776
|
+
disabled: !onQuit,
|
|
7777
|
+
icon: /* @__PURE__ */ jsx9(CloseIcon, { "aria-hidden": "true", className: "size-4" }),
|
|
7778
|
+
label: quitLabel,
|
|
7779
|
+
onSelect: onQuit
|
|
7780
|
+
}
|
|
7781
|
+
)
|
|
7782
|
+
] }) : null
|
|
7783
|
+
]
|
|
7784
|
+
}
|
|
7785
|
+
);
|
|
7786
|
+
}
|
|
7787
|
+
function WorkbenchHostDockContextMenuItem({
|
|
7788
|
+
checked,
|
|
7789
|
+
checkedIcon,
|
|
7790
|
+
disabled,
|
|
7791
|
+
icon,
|
|
7792
|
+
label,
|
|
7793
|
+
onSelect
|
|
7794
|
+
}) {
|
|
7795
|
+
return /* @__PURE__ */ jsxs5(
|
|
7796
|
+
"button",
|
|
7797
|
+
{
|
|
7798
|
+
className: cn(
|
|
7799
|
+
"flex h-8 w-full min-w-0 items-center gap-2 rounded-md px-2 text-left text-sm text-[var(--text-primary)] transition-colors",
|
|
7800
|
+
disabled ? "cursor-default opacity-45" : "hover:bg-transparency-hover focus-visible:bg-transparency-hover focus-visible:outline-none"
|
|
7801
|
+
),
|
|
7802
|
+
disabled,
|
|
7803
|
+
role: "menuitem",
|
|
7804
|
+
type: "button",
|
|
7805
|
+
onClick: () => {
|
|
7806
|
+
if (disabled || !onSelect) {
|
|
7807
|
+
return;
|
|
7808
|
+
}
|
|
7809
|
+
onSelect();
|
|
7810
|
+
},
|
|
7811
|
+
children: [
|
|
7812
|
+
/* @__PURE__ */ jsx9("span", { className: "flex size-4 shrink-0 items-center justify-center text-[var(--text-secondary)]", children: checked && checkedIcon ? checkedIcon : checked ? /* @__PURE__ */ jsx9(
|
|
7813
|
+
CheckIcon,
|
|
7814
|
+
{
|
|
7815
|
+
"aria-hidden": "true",
|
|
7816
|
+
className: "size-4 text-[var(--tutti-purple)]"
|
|
7817
|
+
}
|
|
7818
|
+
) : icon ?? null }),
|
|
7819
|
+
/* @__PURE__ */ jsx9("span", { className: "min-w-0 truncate", children: label })
|
|
7820
|
+
]
|
|
7821
|
+
}
|
|
7822
|
+
);
|
|
7823
|
+
}
|
|
7824
|
+
function WorkbenchHostDockContextMenuSeparator() {
|
|
7825
|
+
return /* @__PURE__ */ jsx9(
|
|
7826
|
+
"div",
|
|
7827
|
+
{
|
|
7828
|
+
"aria-hidden": "true",
|
|
7829
|
+
className: "mx-2 my-1 h-px bg-[var(--border-1)]",
|
|
7830
|
+
role: "separator"
|
|
7831
|
+
}
|
|
7832
|
+
);
|
|
7833
|
+
}
|
|
7124
7834
|
function readPersistedDockPreview(dockPreviewCache, cacheKey) {
|
|
7125
7835
|
if (!cacheKey) {
|
|
7126
7836
|
return Promise.resolve(null);
|
|
@@ -7316,7 +8026,7 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
|
|
|
7316
8026
|
"span",
|
|
7317
8027
|
{
|
|
7318
8028
|
"aria-hidden": "true",
|
|
7319
|
-
className: "pointer-events-none absolute inset-0 z-[3] rounded-
|
|
8029
|
+
className: "pointer-events-none absolute inset-0 z-[3] rounded-md shadow-[inset_0_0_0_2px_var(--border-focus)]",
|
|
7320
8030
|
"data-desktop-dock-popup-card-active-overlay": "true"
|
|
7321
8031
|
}
|
|
7322
8032
|
) : null,
|
|
@@ -7420,6 +8130,7 @@ function WorkbenchHostDock({
|
|
|
7420
8130
|
nodeDefinitions,
|
|
7421
8131
|
onDockEntryAction,
|
|
7422
8132
|
onDockEntryClick,
|
|
8133
|
+
onMissionControlRequestOpen,
|
|
7423
8134
|
workspaceId
|
|
7424
8135
|
}) {
|
|
7425
8136
|
const minimizedNodeIDs = useMemo5(
|
|
@@ -7452,6 +8163,7 @@ function WorkbenchHostDock({
|
|
|
7452
8163
|
/* @__PURE__ */ new Map()
|
|
7453
8164
|
);
|
|
7454
8165
|
const previousAttentionTokenByEntryId = useRef8(/* @__PURE__ */ new Map());
|
|
8166
|
+
const dockEntryClickThrottleUntilRef = useRef8(/* @__PURE__ */ new Map());
|
|
7455
8167
|
const attentionTimeouts = useRef8(
|
|
7456
8168
|
/* @__PURE__ */ new Map()
|
|
7457
8169
|
);
|
|
@@ -7626,9 +8338,9 @@ function WorkbenchHostDock({
|
|
|
7626
8338
|
const minimizedDockSlots = useMemo5(
|
|
7627
8339
|
() => resolveWorkbenchMinimizedDockSlots({
|
|
7628
8340
|
nodeDefinitions,
|
|
7629
|
-
nodes: context.
|
|
8341
|
+
nodes: context.minimizedNodes
|
|
7630
8342
|
}),
|
|
7631
|
-
[context.
|
|
8343
|
+
[context.minimizedNodes, nodeDefinitions]
|
|
7632
8344
|
);
|
|
7633
8345
|
const { promotedNodeId, stackDispatching } = useMinimizedDockStackPromotion(minimizedDockSlots);
|
|
7634
8346
|
const dockItems = useMemo5(
|
|
@@ -7999,6 +8711,19 @@ function WorkbenchHostDock({
|
|
|
7999
8711
|
triggerDockBounce
|
|
8000
8712
|
]
|
|
8001
8713
|
);
|
|
8714
|
+
const isDockEntryClickThrottled = useCallback10(
|
|
8715
|
+
(anchorKey) => {
|
|
8716
|
+
const throttledUntil = dockEntryClickThrottleUntilRef.current.get(anchorKey);
|
|
8717
|
+
return throttledUntil !== void 0 && Date.now() < throttledUntil;
|
|
8718
|
+
},
|
|
8719
|
+
[]
|
|
8720
|
+
);
|
|
8721
|
+
const claimDockEntryClick = useCallback10((anchorKey) => {
|
|
8722
|
+
dockEntryClickThrottleUntilRef.current.set(
|
|
8723
|
+
anchorKey,
|
|
8724
|
+
Date.now() + DOCK_ENTRY_CLICK_THROTTLE_MS
|
|
8725
|
+
);
|
|
8726
|
+
}, []);
|
|
8002
8727
|
const beginDockMinimizedInteraction = useCallback10(
|
|
8003
8728
|
(anchorKey) => {
|
|
8004
8729
|
hoverPanelRestTargetRef.current = null;
|
|
@@ -8156,9 +8881,13 @@ function WorkbenchHostDock({
|
|
|
8156
8881
|
}, [dockPlacement, presentDockItems.length, updateDockScrollState]);
|
|
8157
8882
|
const hasMinimizedPreviewCapture = minimizedDockSlots.some(
|
|
8158
8883
|
(slot) => minimizedDockSlotNodes(slot).some(
|
|
8159
|
-
(node) =>
|
|
8160
|
-
|
|
8161
|
-
|
|
8884
|
+
(node) => (() => {
|
|
8885
|
+
if (context.genie.isPendingMinimizedDockNode(node.id)) {
|
|
8886
|
+
return false;
|
|
8887
|
+
}
|
|
8888
|
+
const minimizedDock = nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock;
|
|
8889
|
+
return minimizedDock?.kind === "snapshot" && Boolean(minimizedDock.capturePreview);
|
|
8890
|
+
})()
|
|
8162
8891
|
)
|
|
8163
8892
|
);
|
|
8164
8893
|
useEffect9(() => {
|
|
@@ -8222,7 +8951,8 @@ function WorkbenchHostDock({
|
|
|
8222
8951
|
);
|
|
8223
8952
|
const captureMinimizedNodePreview = useCallback10(
|
|
8224
8953
|
async (node) => {
|
|
8225
|
-
const
|
|
8954
|
+
const minimizedDock = nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock;
|
|
8955
|
+
const capturePreview = minimizedDock?.kind === "snapshot" ? minimizedDock.capturePreview : void 0;
|
|
8226
8956
|
const externalState = readWorkbenchHostExternalState({
|
|
8227
8957
|
externalStateSource,
|
|
8228
8958
|
node,
|
|
@@ -8250,6 +8980,41 @@ function WorkbenchHostDock({
|
|
|
8250
8980
|
workspaceId
|
|
8251
8981
|
]
|
|
8252
8982
|
);
|
|
8983
|
+
const provideMinimizedNodePreview = useCallback10(
|
|
8984
|
+
(node) => {
|
|
8985
|
+
const minimizedDock = nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock;
|
|
8986
|
+
if (minimizedDock?.kind !== "component") {
|
|
8987
|
+
return null;
|
|
8988
|
+
}
|
|
8989
|
+
const externalState = readWorkbenchHostExternalState({
|
|
8990
|
+
externalStateSource,
|
|
8991
|
+
node,
|
|
8992
|
+
workspaceId
|
|
8993
|
+
});
|
|
8994
|
+
return minimizedDock.providePreview({
|
|
8995
|
+
externalNodeState: externalState.externalNodeState,
|
|
8996
|
+
externalWorkspaceState: externalState.externalWorkspaceState,
|
|
8997
|
+
host,
|
|
8998
|
+
isFocused: context.focusedNodeId === node.id,
|
|
8999
|
+
isMinimized: node.isMinimized,
|
|
9000
|
+
node
|
|
9001
|
+
});
|
|
9002
|
+
},
|
|
9003
|
+
[
|
|
9004
|
+
context.focusedNodeId,
|
|
9005
|
+
externalStateSource,
|
|
9006
|
+
host,
|
|
9007
|
+
nodeDefinitions,
|
|
9008
|
+
workspaceId
|
|
9009
|
+
]
|
|
9010
|
+
);
|
|
9011
|
+
const provideMinimizedNodePreviewForNode = useCallback10(
|
|
9012
|
+
(node) => {
|
|
9013
|
+
const minimizedDock = nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock;
|
|
9014
|
+
return minimizedDock?.kind === "component" ? provideMinimizedNodePreview : void 0;
|
|
9015
|
+
},
|
|
9016
|
+
[nodeDefinitions, provideMinimizedNodePreview]
|
|
9017
|
+
);
|
|
8253
9018
|
if (dockItems.length === 0 && presentDockItems.length === 0) {
|
|
8254
9019
|
return null;
|
|
8255
9020
|
}
|
|
@@ -8303,12 +9068,59 @@ function WorkbenchHostDock({
|
|
|
8303
9068
|
dockSlotRefCallbacksRef.current.set(anchorKey, callback);
|
|
8304
9069
|
return callback;
|
|
8305
9070
|
}, []);
|
|
9071
|
+
const runDockEntryAction = useCallback10(
|
|
9072
|
+
(entryId, actionId) => {
|
|
9073
|
+
const actionKey = dockActionKey(entryId, actionId);
|
|
9074
|
+
if (pendingActionKeys.has(actionKey)) {
|
|
9075
|
+
return;
|
|
9076
|
+
}
|
|
9077
|
+
setPendingActionKeys((current) => {
|
|
9078
|
+
const next = new Set(current);
|
|
9079
|
+
next.add(actionKey);
|
|
9080
|
+
return next;
|
|
9081
|
+
});
|
|
9082
|
+
void (async () => {
|
|
9083
|
+
try {
|
|
9084
|
+
await onDockEntryAction?.({
|
|
9085
|
+
actionId,
|
|
9086
|
+
entryId,
|
|
9087
|
+
host
|
|
9088
|
+
});
|
|
9089
|
+
} catch {
|
|
9090
|
+
} finally {
|
|
9091
|
+
setPendingActionKeys((current) => {
|
|
9092
|
+
if (!current.has(actionKey)) {
|
|
9093
|
+
return current;
|
|
9094
|
+
}
|
|
9095
|
+
const next = new Set(current);
|
|
9096
|
+
next.delete(actionKey);
|
|
9097
|
+
return next;
|
|
9098
|
+
});
|
|
9099
|
+
}
|
|
9100
|
+
})();
|
|
9101
|
+
},
|
|
9102
|
+
[host, onDockEntryAction, pendingActionKeys]
|
|
9103
|
+
);
|
|
8306
9104
|
const popupEntry = activePopup === null ? null : resolvedEntries.find(
|
|
8307
9105
|
(entry) => entry.entry.id === activePopup.entryId
|
|
8308
9106
|
) ?? null;
|
|
8309
9107
|
const activeMinimizedStackSlot = activeMinimizedStackPopup === null ? null : minimizedDockSlots.find(
|
|
8310
9108
|
(slot) => slot.kind === "stack"
|
|
8311
9109
|
) ?? null;
|
|
9110
|
+
const openDockContextMenuNodeIds = popupEntry?.matchedNodes.map((node) => node.id) ?? [];
|
|
9111
|
+
const dockContextMenuInstanceMode = popupEntry === null ? void 0 : resolveDockEntryInstanceMode(popupEntry.entry, nodeDefinitions);
|
|
9112
|
+
const canShowAllWindowsFromDockContextMenu = onMissionControlRequestOpen !== void 0 && dockContextMenuInstanceMode === "multi" && openDockContextMenuNodeIds.length > 1;
|
|
9113
|
+
const fullscreenNodeFromDockContextMenu = popupEntry === null ? null : resolveDockContextMenuFullscreenNode({
|
|
9114
|
+
focusedNodeId: context.focusedNodeId,
|
|
9115
|
+
minimizedNodeIDs,
|
|
9116
|
+
nodeDefinitions,
|
|
9117
|
+
nodes: popupEntry.matchedNodes
|
|
9118
|
+
});
|
|
9119
|
+
const canOpenFromDockContextMenu = popupEntry !== null && popupEntry.matchedNodes.length === 0 && resolveWorkbenchDockEntryClick({
|
|
9120
|
+
entry: popupEntry.entry,
|
|
9121
|
+
instanceMode: dockContextMenuInstanceMode,
|
|
9122
|
+
matchedNodes: popupEntry.matchedNodes
|
|
9123
|
+
}).kind === "launch";
|
|
8312
9124
|
return /* @__PURE__ */ jsxs6(
|
|
8313
9125
|
"div",
|
|
8314
9126
|
{
|
|
@@ -8409,13 +9221,26 @@ function WorkbenchHostDock({
|
|
|
8409
9221
|
className: "desktop-dock__btn",
|
|
8410
9222
|
"data-interactive": clickResolution.kind === "blocked" ? "false" : "true",
|
|
8411
9223
|
type: "button",
|
|
8412
|
-
onPointerDown: () => {
|
|
9224
|
+
onPointerDown: (event) => {
|
|
9225
|
+
if (event.button !== 0) {
|
|
9226
|
+
return;
|
|
9227
|
+
}
|
|
8413
9228
|
if (clickResolution.kind === "blocked") {
|
|
8414
9229
|
return;
|
|
8415
9230
|
}
|
|
9231
|
+
if (isDockEntryClickThrottled(anchorKey)) {
|
|
9232
|
+
return;
|
|
9233
|
+
}
|
|
8416
9234
|
beginDockIconInteraction(anchorKey);
|
|
8417
9235
|
},
|
|
8418
9236
|
onClick: (event) => {
|
|
9237
|
+
if (clickResolution.kind === "blocked") {
|
|
9238
|
+
return;
|
|
9239
|
+
}
|
|
9240
|
+
if (isDockEntryClickThrottled(anchorKey)) {
|
|
9241
|
+
return;
|
|
9242
|
+
}
|
|
9243
|
+
claimDockEntryClick(anchorKey);
|
|
8419
9244
|
logWorkbenchDockDebug("dock.click", debugDiagnostics, {
|
|
8420
9245
|
anchorKey,
|
|
8421
9246
|
clickResolution,
|
|
@@ -8442,14 +9267,16 @@ function WorkbenchHostDock({
|
|
|
8442
9267
|
switch (clickResolution.kind) {
|
|
8443
9268
|
case "focus-node":
|
|
8444
9269
|
closePopup();
|
|
8445
|
-
void
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
|
|
8449
|
-
|
|
8450
|
-
|
|
8451
|
-
|
|
8452
|
-
|
|
9270
|
+
void (async () => {
|
|
9271
|
+
try {
|
|
9272
|
+
await onDockEntryClick?.({
|
|
9273
|
+
entryId: entry.id,
|
|
9274
|
+
host,
|
|
9275
|
+
nodeId: clickResolution.nodeId
|
|
9276
|
+
});
|
|
9277
|
+
} catch {
|
|
9278
|
+
}
|
|
9279
|
+
})();
|
|
8453
9280
|
context.genie.launchNodeFromAnchor(
|
|
8454
9281
|
anchorKey,
|
|
8455
9282
|
clickResolution.nodeId,
|
|
@@ -8480,6 +9307,7 @@ function WorkbenchHostDock({
|
|
|
8480
9307
|
top: rect.top,
|
|
8481
9308
|
width: rect.width
|
|
8482
9309
|
},
|
|
9310
|
+
kind: "preview",
|
|
8483
9311
|
entryId: entry.id
|
|
8484
9312
|
}
|
|
8485
9313
|
);
|
|
@@ -8487,14 +9315,16 @@ function WorkbenchHostDock({
|
|
|
8487
9315
|
}
|
|
8488
9316
|
case "action":
|
|
8489
9317
|
closePopup();
|
|
8490
|
-
void
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
|
|
8495
|
-
|
|
8496
|
-
|
|
8497
|
-
|
|
9318
|
+
void (async () => {
|
|
9319
|
+
try {
|
|
9320
|
+
await onDockEntryAction?.({
|
|
9321
|
+
actionId: clickResolution.actionId,
|
|
9322
|
+
entryId: entry.id,
|
|
9323
|
+
host
|
|
9324
|
+
});
|
|
9325
|
+
} catch {
|
|
9326
|
+
}
|
|
9327
|
+
})();
|
|
8498
9328
|
return;
|
|
8499
9329
|
case "launch":
|
|
8500
9330
|
closePopup();
|
|
@@ -8509,10 +9339,36 @@ function WorkbenchHostDock({
|
|
|
8509
9339
|
})
|
|
8510
9340
|
);
|
|
8511
9341
|
return;
|
|
8512
|
-
case "blocked":
|
|
8513
|
-
return;
|
|
8514
9342
|
}
|
|
8515
9343
|
},
|
|
9344
|
+
onContextMenu: (event) => {
|
|
9345
|
+
if (clickResolution.kind === "blocked" || !dockEntryHasContextMenu(entry, resolvedEntry)) {
|
|
9346
|
+
return;
|
|
9347
|
+
}
|
|
9348
|
+
event.preventDefault();
|
|
9349
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
9350
|
+
logWorkbenchDockDebug(
|
|
9351
|
+
"dock.popup.context_menu",
|
|
9352
|
+
debugDiagnostics,
|
|
9353
|
+
{
|
|
9354
|
+
anchorKey,
|
|
9355
|
+
entryId: entry.id,
|
|
9356
|
+
matchedNodeCount: resolvedEntry.matchedNodes.length,
|
|
9357
|
+
typeId: entry.typeId,
|
|
9358
|
+
workspaceId
|
|
9359
|
+
}
|
|
9360
|
+
);
|
|
9361
|
+
setActivePopup({
|
|
9362
|
+
anchorRect: {
|
|
9363
|
+
height: rect.height,
|
|
9364
|
+
left: rect.left,
|
|
9365
|
+
top: rect.top,
|
|
9366
|
+
width: rect.width
|
|
9367
|
+
},
|
|
9368
|
+
kind: "context-menu",
|
|
9369
|
+
entryId: entry.id
|
|
9370
|
+
});
|
|
9371
|
+
},
|
|
8516
9372
|
children: /* @__PURE__ */ jsxs6(
|
|
8517
9373
|
"span",
|
|
8518
9374
|
{
|
|
@@ -8641,7 +9497,10 @@ function WorkbenchHostDock({
|
|
|
8641
9497
|
className: "desktop-dock__btn desktop-dock__minimized-btn",
|
|
8642
9498
|
"data-interactive": "true",
|
|
8643
9499
|
type: "button",
|
|
8644
|
-
onPointerDown: () => {
|
|
9500
|
+
onPointerDown: (event) => {
|
|
9501
|
+
if (event.button !== 0) {
|
|
9502
|
+
return;
|
|
9503
|
+
}
|
|
8645
9504
|
beginDockMinimizedInteraction();
|
|
8646
9505
|
},
|
|
8647
9506
|
onClick: (event) => {
|
|
@@ -8683,9 +9542,12 @@ function WorkbenchHostDock({
|
|
|
8683
9542
|
className: `desktop-dock__minimized-stack-layer desktop-dock__minimized-stack-layer--${index}`,
|
|
8684
9543
|
dockPreviewCache,
|
|
8685
9544
|
node: node2,
|
|
9545
|
+
providePreview: provideMinimizedNodePreviewForNode(
|
|
9546
|
+
node2
|
|
9547
|
+
),
|
|
8686
9548
|
workspaceId
|
|
8687
9549
|
},
|
|
8688
|
-
node2
|
|
9550
|
+
minimizedDockPreviewFreezeKey(node2)
|
|
8689
9551
|
);
|
|
8690
9552
|
}
|
|
8691
9553
|
return /* @__PURE__ */ jsx10(
|
|
@@ -8753,6 +9615,7 @@ function WorkbenchHostDock({
|
|
|
8753
9615
|
);
|
|
8754
9616
|
}
|
|
8755
9617
|
const node = slot.node;
|
|
9618
|
+
const isPendingMinimizedNode = context.genie.isPendingMinimizedDockNode(node.id);
|
|
8756
9619
|
const labelTooltipTarget = dockLabelTooltipTarget(
|
|
8757
9620
|
`minimized-node:${node.id}`,
|
|
8758
9621
|
node.title
|
|
@@ -8763,8 +9626,12 @@ function WorkbenchHostDock({
|
|
|
8763
9626
|
"aria-label": i18n.t("launch", { title: node.title }),
|
|
8764
9627
|
className: "desktop-dock__btn desktop-dock__minimized-btn",
|
|
8765
9628
|
"data-interactive": "true",
|
|
9629
|
+
disabled: isPendingMinimizedNode,
|
|
8766
9630
|
type: "button",
|
|
8767
|
-
onPointerDown: () => {
|
|
9631
|
+
onPointerDown: (event) => {
|
|
9632
|
+
if (event.button !== 0 || isPendingMinimizedNode) {
|
|
9633
|
+
return;
|
|
9634
|
+
}
|
|
8768
9635
|
const restoreIntent = resolveWorkbenchMinimizedDockRestoreIntent({
|
|
8769
9636
|
nodeId: node.id,
|
|
8770
9637
|
slots: minimizedDockSlots,
|
|
@@ -8780,6 +9647,9 @@ function WorkbenchHostDock({
|
|
|
8780
9647
|
beginDockMinimizedInteraction();
|
|
8781
9648
|
},
|
|
8782
9649
|
onClick: () => {
|
|
9650
|
+
if (isPendingMinimizedNode) {
|
|
9651
|
+
return;
|
|
9652
|
+
}
|
|
8783
9653
|
const restoreIntent = resolveWorkbenchMinimizedDockRestoreIntent({
|
|
8784
9654
|
nodeId: node.id,
|
|
8785
9655
|
slots: minimizedDockSlots,
|
|
@@ -8809,11 +9679,14 @@ function WorkbenchHostDock({
|
|
|
8809
9679
|
children: /* @__PURE__ */ jsx10(
|
|
8810
9680
|
WorkbenchHostDockMinimizedNodePreview,
|
|
8811
9681
|
{
|
|
8812
|
-
capturePreview: captureMinimizedNodePreview,
|
|
8813
|
-
|
|
9682
|
+
capturePreview: isPendingMinimizedNode ? void 0 : captureMinimizedNodePreview,
|
|
9683
|
+
deferPreview: isPendingMinimizedNode,
|
|
9684
|
+
dockPreviewCache: isPendingMinimizedNode ? void 0 : dockPreviewCache,
|
|
8814
9685
|
node,
|
|
9686
|
+
providePreview: isPendingMinimizedNode ? void 0 : provideMinimizedNodePreviewForNode(node),
|
|
8815
9687
|
workspaceId
|
|
8816
|
-
}
|
|
9688
|
+
},
|
|
9689
|
+
minimizedDockPreviewFreezeKey(node)
|
|
8817
9690
|
)
|
|
8818
9691
|
}
|
|
8819
9692
|
);
|
|
@@ -8828,6 +9701,7 @@ function WorkbenchHostDock({
|
|
|
8828
9701
|
"data-dock-label-tooltip-key": labelTooltipTarget.key,
|
|
8829
9702
|
"data-dock-label-tooltip-label": labelTooltipTarget.label,
|
|
8830
9703
|
"data-node-state": "minimized",
|
|
9704
|
+
"data-pending-minimize": isPendingMinimizedNode ? "true" : void 0,
|
|
8831
9705
|
"data-presence": dockItem.presence,
|
|
8832
9706
|
"data-promoted-from-stack": promotedNodeId === node.id ? "true" : void 0,
|
|
8833
9707
|
"data-section-id": "minimized",
|
|
@@ -8929,7 +9803,27 @@ function WorkbenchHostDock({
|
|
|
8929
9803
|
{
|
|
8930
9804
|
anchorRect: activePopup.anchorRect,
|
|
8931
9805
|
placement: dockPlacement,
|
|
9806
|
+
canEnterFullscreen: fullscreenNodeFromDockContextMenu !== null,
|
|
9807
|
+
canShowAllWindows: canShowAllWindowsFromDockContextMenu,
|
|
8932
9808
|
debugDiagnostics,
|
|
9809
|
+
dockRetention: popupEntry.entry.dockRetention ? {
|
|
9810
|
+
checked: popupEntry.entry.dockRetention.retained,
|
|
9811
|
+
disabled: popupEntry.entry.dockRetention.disabled === true || pendingActionKeys.has(
|
|
9812
|
+
dockActionKey(
|
|
9813
|
+
popupEntry.entry.id,
|
|
9814
|
+
popupEntry.entry.dockRetention.actionId
|
|
9815
|
+
)
|
|
9816
|
+
),
|
|
9817
|
+
label: i18n.t(
|
|
9818
|
+
popupEntry.entry.dockRetention.retained ? "dockContextMenu.removeFromDock" : "dockContextMenu.keepInDock"
|
|
9819
|
+
),
|
|
9820
|
+
pendingLabel: pendingActionKeys.has(
|
|
9821
|
+
dockActionKey(
|
|
9822
|
+
popupEntry.entry.id,
|
|
9823
|
+
popupEntry.entry.dockRetention.actionId
|
|
9824
|
+
)
|
|
9825
|
+
) ? popupEntry.entry.dockRetention.pendingLabel : void 0
|
|
9826
|
+
} : null,
|
|
8933
9827
|
capturePreview: popupEntry.entry.capturePopupItemPreview ? async (item) => {
|
|
8934
9828
|
const previewImageUrl = await Promise.resolve(
|
|
8935
9829
|
popupEntry.entry.capturePopupItemPreview?.(item) ?? null
|
|
@@ -8978,7 +9872,10 @@ function WorkbenchHostDock({
|
|
|
8978
9872
|
label: popupEntry.entry.label,
|
|
8979
9873
|
labelMode: popupEntry.entry.popupCardLabelMode,
|
|
8980
9874
|
newWindowLabel: i18n.t("newWindow"),
|
|
9875
|
+
openLabel: i18n.t("dockContextMenu.open"),
|
|
8981
9876
|
closeWindowLabel: (title) => i18n.t("closeWindow", { title }),
|
|
9877
|
+
fullscreenLabel: i18n.t("dockContextMenu.fullscreen"),
|
|
9878
|
+
hideLabel: i18n.t("dockContextMenu.hide"),
|
|
8982
9879
|
onClose: () => {
|
|
8983
9880
|
logWorkbenchDockDebug(
|
|
8984
9881
|
"dock.popup.close_requested",
|
|
@@ -9013,16 +9910,46 @@ function WorkbenchHostDock({
|
|
|
9013
9910
|
})
|
|
9014
9911
|
);
|
|
9015
9912
|
},
|
|
9913
|
+
onEnterFullscreen: () => {
|
|
9914
|
+
if (!fullscreenNodeFromDockContextMenu) {
|
|
9915
|
+
return;
|
|
9916
|
+
}
|
|
9917
|
+
context.controller.commands.enterFullscreen(
|
|
9918
|
+
fullscreenNodeFromDockContextMenu.id
|
|
9919
|
+
);
|
|
9920
|
+
closePopup();
|
|
9921
|
+
},
|
|
9922
|
+
onHide: () => {
|
|
9923
|
+
for (const node of popupEntry.matchedNodes) {
|
|
9924
|
+
if (!minimizedNodeIDs.has(node.id)) {
|
|
9925
|
+
host.minimizeNode(node.id);
|
|
9926
|
+
}
|
|
9927
|
+
}
|
|
9928
|
+
closePopup();
|
|
9929
|
+
},
|
|
9930
|
+
onRunDockRetentionAction: popupEntry.entry.dockRetention ? () => {
|
|
9931
|
+
const dockRetention = popupEntry.entry.dockRetention;
|
|
9932
|
+
if (!dockRetention || dockRetention.disabled === true) {
|
|
9933
|
+
return;
|
|
9934
|
+
}
|
|
9935
|
+
runDockEntryAction(
|
|
9936
|
+
popupEntry.entry.id,
|
|
9937
|
+
dockRetention.actionId
|
|
9938
|
+
);
|
|
9939
|
+
closePopup();
|
|
9940
|
+
} : void 0,
|
|
9016
9941
|
onSelectNode: (nodeId) => {
|
|
9017
9942
|
closePopup();
|
|
9018
|
-
void
|
|
9019
|
-
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
|
|
9025
|
-
|
|
9943
|
+
void (async () => {
|
|
9944
|
+
try {
|
|
9945
|
+
await onDockEntryClick?.({
|
|
9946
|
+
entryId: popupEntry.entry.id,
|
|
9947
|
+
host,
|
|
9948
|
+
nodeId
|
|
9949
|
+
});
|
|
9950
|
+
} catch {
|
|
9951
|
+
}
|
|
9952
|
+
})();
|
|
9026
9953
|
context.genie.launchNodeFromAnchor(
|
|
9027
9954
|
anchorKeyFromPopupEntry(popupEntry),
|
|
9028
9955
|
nodeId,
|
|
@@ -9031,11 +9958,35 @@ function WorkbenchHostDock({
|
|
|
9031
9958
|
}
|
|
9032
9959
|
);
|
|
9033
9960
|
},
|
|
9961
|
+
onShowAllWindows: () => {
|
|
9962
|
+
closePopup();
|
|
9963
|
+
for (const node of popupEntry.matchedNodes) {
|
|
9964
|
+
if (minimizedNodeIDs.has(node.id)) {
|
|
9965
|
+
context.controller.commands.restoreNode(node.id);
|
|
9966
|
+
}
|
|
9967
|
+
}
|
|
9968
|
+
window.requestAnimationFrame(() => {
|
|
9969
|
+
onMissionControlRequestOpen?.("activate", {
|
|
9970
|
+
nodeIds: openDockContextMenuNodeIds,
|
|
9971
|
+
trigger: "dock-context-menu"
|
|
9972
|
+
});
|
|
9973
|
+
});
|
|
9974
|
+
},
|
|
9975
|
+
onQuit: () => {
|
|
9976
|
+
for (const node of popupEntry.matchedNodes) {
|
|
9977
|
+
host.requestNodeClose(node.id);
|
|
9978
|
+
}
|
|
9979
|
+
closePopup();
|
|
9980
|
+
},
|
|
9981
|
+
quitLabel: i18n.t("dockContextMenu.quit"),
|
|
9034
9982
|
showCreateNew: canCreateNewWindow(
|
|
9035
9983
|
popupEntry.entry,
|
|
9036
|
-
|
|
9984
|
+
dockContextMenuInstanceMode
|
|
9037
9985
|
),
|
|
9038
|
-
|
|
9986
|
+
showOpen: canOpenFromDockContextMenu,
|
|
9987
|
+
showAllWindowsLabel: i18n.t("dockContextMenu.showAllWindows"),
|
|
9988
|
+
resolveDockPreviewCacheKey: (node) => resolveDockPreviewCacheKey(workspaceId, node),
|
|
9989
|
+
variant: activePopup.kind === "context-menu" ? "context-menu" : "default"
|
|
9039
9990
|
}
|
|
9040
9991
|
) : null,
|
|
9041
9992
|
activeMinimizedStackSlot && activeMinimizedStackPopup ? /* @__PURE__ */ jsx10(
|
|
@@ -9055,6 +10006,7 @@ function WorkbenchHostDock({
|
|
|
9055
10006
|
node,
|
|
9056
10007
|
workspaceId
|
|
9057
10008
|
});
|
|
10009
|
+
const minimizedDock = nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock;
|
|
9058
10010
|
return {
|
|
9059
10011
|
externalNodeState: externalState.externalNodeState,
|
|
9060
10012
|
externalWorkspaceState: externalState.externalWorkspaceState,
|
|
@@ -9062,10 +10014,8 @@ function WorkbenchHostDock({
|
|
|
9062
10014
|
isFocused: context.focusedNodeId === node.id,
|
|
9063
10015
|
isMinimized: true,
|
|
9064
10016
|
node,
|
|
9065
|
-
preview:
|
|
9066
|
-
const previewImageUrl = readCachedWorkbenchNodePreviewImage(
|
|
9067
|
-
node.id
|
|
9068
|
-
);
|
|
10017
|
+
preview: minimizedDock?.kind === "component" ? provideMinimizedNodePreview(node) ?? null : minimizedDock?.kind === "snapshot" && minimizedDock.capturePreview ? null : (() => {
|
|
10018
|
+
const previewImageUrl = readCachedWorkbenchNodePreviewImage(node.id);
|
|
9069
10019
|
return previewImageUrl ? { kind: "image", src: previewImageUrl } : null;
|
|
9070
10020
|
})(),
|
|
9071
10021
|
previewRevision: null,
|
|
@@ -9133,14 +10083,69 @@ function WorkbenchHostDock({
|
|
|
9133
10083
|
function WorkbenchHostDockMinimizedNodePreview({
|
|
9134
10084
|
capturePreview,
|
|
9135
10085
|
className,
|
|
10086
|
+
deferPreview = false,
|
|
9136
10087
|
dockPreviewCache,
|
|
9137
10088
|
node,
|
|
10089
|
+
providePreview,
|
|
9138
10090
|
workspaceId
|
|
9139
10091
|
}) {
|
|
10092
|
+
const [componentPreview, setComponentPreview] = useState8(void 0);
|
|
9140
10093
|
const [previewImageUrl, setPreviewImageUrl] = useState8(
|
|
9141
|
-
() => readCachedWorkbenchNodePreviewImage(node.id)
|
|
10094
|
+
() => deferPreview || providePreview ? null : readCachedWorkbenchNodePreviewImage(node.id)
|
|
9142
10095
|
);
|
|
9143
10096
|
useEffect9(() => {
|
|
10097
|
+
if (deferPreview || !providePreview || componentPreview !== void 0) {
|
|
10098
|
+
return void 0;
|
|
10099
|
+
}
|
|
10100
|
+
let cancelled = false;
|
|
10101
|
+
let frameId = null;
|
|
10102
|
+
let idleId = null;
|
|
10103
|
+
let timeoutId = null;
|
|
10104
|
+
const setDeferredComponentPreview = () => {
|
|
10105
|
+
if (cancelled) {
|
|
10106
|
+
return;
|
|
10107
|
+
}
|
|
10108
|
+
setComponentPreview(providePreview(node) ?? null);
|
|
10109
|
+
};
|
|
10110
|
+
const scheduler = globalThis;
|
|
10111
|
+
if (typeof scheduler.requestIdleCallback === "function") {
|
|
10112
|
+
idleId = scheduler.requestIdleCallback(setDeferredComponentPreview, {
|
|
10113
|
+
timeout: 250
|
|
10114
|
+
});
|
|
10115
|
+
} else if (typeof scheduler.requestAnimationFrame === "function") {
|
|
10116
|
+
frameId = scheduler.requestAnimationFrame(() => {
|
|
10117
|
+
frameId = null;
|
|
10118
|
+
timeoutId = globalThis.setTimeout(setDeferredComponentPreview, 0);
|
|
10119
|
+
});
|
|
10120
|
+
} else {
|
|
10121
|
+
timeoutId = globalThis.setTimeout(setDeferredComponentPreview, 0);
|
|
10122
|
+
}
|
|
10123
|
+
return () => {
|
|
10124
|
+
cancelled = true;
|
|
10125
|
+
if (idleId !== null && typeof scheduler.cancelIdleCallback === "function") {
|
|
10126
|
+
scheduler.cancelIdleCallback(idleId);
|
|
10127
|
+
}
|
|
10128
|
+
if (frameId !== null && typeof scheduler.cancelAnimationFrame === "function") {
|
|
10129
|
+
scheduler.cancelAnimationFrame(frameId);
|
|
10130
|
+
}
|
|
10131
|
+
if (timeoutId !== null) {
|
|
10132
|
+
globalThis.clearTimeout(timeoutId);
|
|
10133
|
+
}
|
|
10134
|
+
};
|
|
10135
|
+
}, [
|
|
10136
|
+
componentPreview,
|
|
10137
|
+
deferPreview,
|
|
10138
|
+
node.data.instanceId,
|
|
10139
|
+
node.data.instanceKey,
|
|
10140
|
+
node.data.typeId,
|
|
10141
|
+
node.id,
|
|
10142
|
+
node.minimizedAtUnixMs,
|
|
10143
|
+
providePreview
|
|
10144
|
+
]);
|
|
10145
|
+
useEffect9(() => {
|
|
10146
|
+
if (deferPreview || providePreview) {
|
|
10147
|
+
return void 0;
|
|
10148
|
+
}
|
|
9144
10149
|
let cancelled = false;
|
|
9145
10150
|
const cachedPreviewImageUrl = readCachedWorkbenchNodePreviewImage(node.id);
|
|
9146
10151
|
setPreviewImageUrl(cachedPreviewImageUrl);
|
|
@@ -9182,14 +10187,22 @@ function WorkbenchHostDockMinimizedNodePreview({
|
|
|
9182
10187
|
};
|
|
9183
10188
|
}, [
|
|
9184
10189
|
capturePreview,
|
|
10190
|
+
deferPreview,
|
|
9185
10191
|
dockPreviewCache,
|
|
9186
10192
|
node.data.instanceId,
|
|
9187
10193
|
node.data.instanceKey,
|
|
9188
10194
|
node.data.typeId,
|
|
9189
10195
|
node.id,
|
|
9190
10196
|
node.minimizedAtUnixMs,
|
|
10197
|
+
providePreview,
|
|
9191
10198
|
workspaceId
|
|
9192
10199
|
]);
|
|
10200
|
+
if (deferPreview) {
|
|
10201
|
+
return renderMinimizedDockPreviewPlaceholder(className);
|
|
10202
|
+
}
|
|
10203
|
+
if (componentPreview) {
|
|
10204
|
+
return renderMinimizedDockPreviewContent(componentPreview, className);
|
|
10205
|
+
}
|
|
9193
10206
|
if (previewImageUrl) {
|
|
9194
10207
|
return /* @__PURE__ */ jsx10(
|
|
9195
10208
|
"span",
|
|
@@ -9212,6 +10225,9 @@ function WorkbenchHostDockMinimizedNodePreview({
|
|
|
9212
10225
|
}
|
|
9213
10226
|
);
|
|
9214
10227
|
}
|
|
10228
|
+
return renderMinimizedDockPreviewPlaceholder(className);
|
|
10229
|
+
}
|
|
10230
|
+
function renderMinimizedDockPreviewPlaceholder(className) {
|
|
9215
10231
|
return /* @__PURE__ */ jsxs6(
|
|
9216
10232
|
"span",
|
|
9217
10233
|
{
|
|
@@ -9225,9 +10241,101 @@ function WorkbenchHostDockMinimizedNodePreview({
|
|
|
9225
10241
|
}
|
|
9226
10242
|
);
|
|
9227
10243
|
}
|
|
10244
|
+
function renderMinimizedDockPreviewContent(preview, className) {
|
|
10245
|
+
if (preview.kind === "image") {
|
|
10246
|
+
return /* @__PURE__ */ jsx10(
|
|
10247
|
+
"span",
|
|
10248
|
+
{
|
|
10249
|
+
className: [
|
|
10250
|
+
"desktop-dock__minimized-preview",
|
|
10251
|
+
"desktop-dock__minimized-preview--snapshot",
|
|
10252
|
+
className
|
|
10253
|
+
].filter(Boolean).join(" "),
|
|
10254
|
+
"aria-hidden": "true",
|
|
10255
|
+
children: /* @__PURE__ */ jsx10(
|
|
10256
|
+
"img",
|
|
10257
|
+
{
|
|
10258
|
+
alt: "",
|
|
10259
|
+
className: "desktop-dock__minimized-preview-image",
|
|
10260
|
+
draggable: false,
|
|
10261
|
+
src: preview.src
|
|
10262
|
+
}
|
|
10263
|
+
)
|
|
10264
|
+
}
|
|
10265
|
+
);
|
|
10266
|
+
}
|
|
10267
|
+
return /* @__PURE__ */ jsx10(
|
|
10268
|
+
WorkbenchHostDockFrozenComponentPreview,
|
|
10269
|
+
{
|
|
10270
|
+
className,
|
|
10271
|
+
preview
|
|
10272
|
+
}
|
|
10273
|
+
);
|
|
10274
|
+
}
|
|
10275
|
+
function WorkbenchHostDockFrozenComponentPreview({
|
|
10276
|
+
className,
|
|
10277
|
+
preview
|
|
10278
|
+
}) {
|
|
10279
|
+
const sourceRef = useRef8(null);
|
|
10280
|
+
const [frozenMarkup, setFrozenMarkup] = useState8(null);
|
|
10281
|
+
useLayoutEffect5(() => {
|
|
10282
|
+
if (frozenMarkup !== null) {
|
|
10283
|
+
return;
|
|
10284
|
+
}
|
|
10285
|
+
setFrozenMarkup(sourceRef.current?.innerHTML ?? "");
|
|
10286
|
+
}, [frozenMarkup]);
|
|
10287
|
+
return /* @__PURE__ */ jsx10(
|
|
10288
|
+
"span",
|
|
10289
|
+
{
|
|
10290
|
+
className: [
|
|
10291
|
+
"desktop-dock__minimized-preview",
|
|
10292
|
+
"desktop-dock__minimized-preview--component",
|
|
10293
|
+
className
|
|
10294
|
+
].filter(Boolean).join(" "),
|
|
10295
|
+
"aria-hidden": "true",
|
|
10296
|
+
children: frozenMarkup === null ? /* @__PURE__ */ jsx10(
|
|
10297
|
+
"span",
|
|
10298
|
+
{
|
|
10299
|
+
ref: sourceRef,
|
|
10300
|
+
className: "desktop-dock__minimized-preview-freeze-source",
|
|
10301
|
+
children: preview.element
|
|
10302
|
+
}
|
|
10303
|
+
) : /* @__PURE__ */ jsx10(
|
|
10304
|
+
"span",
|
|
10305
|
+
{
|
|
10306
|
+
className: "desktop-dock__minimized-preview-frozen-content",
|
|
10307
|
+
dangerouslySetInnerHTML: { __html: frozenMarkup }
|
|
10308
|
+
}
|
|
10309
|
+
)
|
|
10310
|
+
}
|
|
10311
|
+
);
|
|
10312
|
+
}
|
|
10313
|
+
function minimizedDockPreviewFreezeKey(node) {
|
|
10314
|
+
return `${node.id}:${node.minimizedAtUnixMs ?? "pending"}`;
|
|
10315
|
+
}
|
|
9228
10316
|
function dockEntryHasHoverPanel(entry) {
|
|
9229
10317
|
return Boolean(entry.state?.reason?.trim()) || (entry.hoverActions?.length ?? 0) > 0;
|
|
9230
10318
|
}
|
|
10319
|
+
function dockEntryHasContextMenu(entry, resolvedEntry) {
|
|
10320
|
+
if (resolvedEntry.matchedNodes.length > 0 || entry.dockRetention) {
|
|
10321
|
+
return true;
|
|
10322
|
+
}
|
|
10323
|
+
return entry.clickActionId === void 0;
|
|
10324
|
+
}
|
|
10325
|
+
function resolveDockContextMenuFullscreenNode({
|
|
10326
|
+
focusedNodeId,
|
|
10327
|
+
minimizedNodeIDs,
|
|
10328
|
+
nodeDefinitions,
|
|
10329
|
+
nodes
|
|
10330
|
+
}) {
|
|
10331
|
+
const candidates = nodes.filter((node) => {
|
|
10332
|
+
if (node.displayMode === "fullscreen" || minimizedNodeIDs.has(node.id)) {
|
|
10333
|
+
return false;
|
|
10334
|
+
}
|
|
10335
|
+
return nodeDefinitions.get(node.data.typeId)?.window?.fullscreenable !== false;
|
|
10336
|
+
});
|
|
10337
|
+
return candidates.find((node) => node.id === focusedNodeId) ?? candidates[0] ?? null;
|
|
10338
|
+
}
|
|
9231
10339
|
function dockLabelTooltipTarget(key, label) {
|
|
9232
10340
|
return { key, label: label.trim() };
|
|
9233
10341
|
}
|
|
@@ -9347,23 +10455,25 @@ function WorkbenchHostDockHoverPanel({
|
|
|
9347
10455
|
next.add(actionKey);
|
|
9348
10456
|
return next;
|
|
9349
10457
|
});
|
|
9350
|
-
void
|
|
9351
|
-
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
|
|
9355
|
-
|
|
9356
|
-
|
|
9357
|
-
|
|
9358
|
-
|
|
9359
|
-
|
|
9360
|
-
|
|
9361
|
-
|
|
9362
|
-
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
9366
|
-
|
|
10458
|
+
void (async () => {
|
|
10459
|
+
try {
|
|
10460
|
+
await onDockEntryAction?.({
|
|
10461
|
+
actionId: action.id,
|
|
10462
|
+
entryId: entry.id,
|
|
10463
|
+
host
|
|
10464
|
+
});
|
|
10465
|
+
} catch {
|
|
10466
|
+
} finally {
|
|
10467
|
+
setPendingActionKeys((current) => {
|
|
10468
|
+
if (!current.has(actionKey)) {
|
|
10469
|
+
return current;
|
|
10470
|
+
}
|
|
10471
|
+
const next = new Set(current);
|
|
10472
|
+
next.delete(actionKey);
|
|
10473
|
+
return next;
|
|
10474
|
+
});
|
|
10475
|
+
}
|
|
10476
|
+
})();
|
|
9367
10477
|
},
|
|
9368
10478
|
children: isPending ? action.pendingLabel ?? action.label : action.label
|
|
9369
10479
|
},
|
|
@@ -9838,6 +10948,7 @@ function dockWallpaperToneMapsEqual(left, right) {
|
|
|
9838
10948
|
return true;
|
|
9839
10949
|
}
|
|
9840
10950
|
var DOCK_BOUNCE_MS = 600;
|
|
10951
|
+
var DOCK_ENTRY_CLICK_THROTTLE_MS = DOCK_BOUNCE_MS;
|
|
9841
10952
|
function useDockBounce(slotRefs) {
|
|
9842
10953
|
const timeoutsRef = useRef8(/* @__PURE__ */ new Map());
|
|
9843
10954
|
const clearDockBounce = useCallback10(
|
|
@@ -10027,8 +11138,8 @@ function createWorkbenchHostNodeHeaderContext({
|
|
|
10027
11138
|
}
|
|
10028
11139
|
|
|
10029
11140
|
// src/host/WorkbenchHostWindowActions.tsx
|
|
10030
|
-
import { Button as Button5, CloseIcon as CloseIcon2, MinimizeIcon } from "@tutti-os/ui-system";
|
|
10031
|
-
import { Fragment as
|
|
11141
|
+
import { Button as Button5, CloseIcon as CloseIcon2, MinimizeIcon as MinimizeIcon2 } from "@tutti-os/ui-system";
|
|
11142
|
+
import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
10032
11143
|
function WorkbenchHostWindowActions({
|
|
10033
11144
|
context,
|
|
10034
11145
|
host,
|
|
@@ -10041,7 +11152,7 @@ function WorkbenchHostWindowActions({
|
|
|
10041
11152
|
}
|
|
10042
11153
|
const minimizable = definition.window?.minimizable !== false;
|
|
10043
11154
|
const closable = definition.window?.closable !== false;
|
|
10044
|
-
return /* @__PURE__ */ jsxs7(
|
|
11155
|
+
return /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
10045
11156
|
minimizable ? /* @__PURE__ */ jsx11(
|
|
10046
11157
|
Button5,
|
|
10047
11158
|
{
|
|
@@ -10057,7 +11168,7 @@ function WorkbenchHostWindowActions({
|
|
|
10057
11168
|
() => context.controller.commands.minimizeNode(context.node.id)
|
|
10058
11169
|
);
|
|
10059
11170
|
},
|
|
10060
|
-
children: /* @__PURE__ */ jsx11(
|
|
11171
|
+
children: /* @__PURE__ */ jsx11(MinimizeIcon2, { className: "size-3.5" })
|
|
10061
11172
|
}
|
|
10062
11173
|
) : null,
|
|
10063
11174
|
closable ? /* @__PURE__ */ jsx11(
|
|
@@ -10140,7 +11251,8 @@ function useWorkbenchHostSurfaceRenderers(input) {
|
|
|
10140
11251
|
const captureNodePreviewImage = useCallback11(
|
|
10141
11252
|
async (node) => {
|
|
10142
11253
|
const definition = input.nodeDefinitionByType.get(node.data.typeId);
|
|
10143
|
-
const
|
|
11254
|
+
const minimizedDock = definition?.window?.minimizedDock;
|
|
11255
|
+
const capturePreview = minimizedDock?.kind === "snapshot" ? minimizedDock.capturePreview : void 0;
|
|
10144
11256
|
const snapshot = input.hostSession.getSnapshot();
|
|
10145
11257
|
const externalState = readWorkbenchHostExternalState({
|
|
10146
11258
|
externalStateSource: input.externalStateSource,
|
|
@@ -10198,6 +11310,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
|
|
|
10198
11310
|
nodeDefinitions: input.nodeDefinitionByType,
|
|
10199
11311
|
onDockEntryAction: input.onDockEntryAction,
|
|
10200
11312
|
onDockEntryClick: input.onDockEntryClick,
|
|
11313
|
+
onMissionControlRequestOpen: input.onMissionControlRequestOpen,
|
|
10201
11314
|
workspaceId: input.workspaceId
|
|
10202
11315
|
}
|
|
10203
11316
|
)
|
|
@@ -10216,6 +11329,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
|
|
|
10216
11329
|
input.nodeDefinitionByType,
|
|
10217
11330
|
input.onDockEntryAction,
|
|
10218
11331
|
input.onDockEntryClick,
|
|
11332
|
+
input.onMissionControlRequestOpen,
|
|
10219
11333
|
input.workspaceId
|
|
10220
11334
|
]
|
|
10221
11335
|
);
|
|
@@ -10305,17 +11419,30 @@ function useWorkbenchHostSurfaceRenderers(input) {
|
|
|
10305
11419
|
},
|
|
10306
11420
|
[input.nodeDefinitionByType]
|
|
10307
11421
|
);
|
|
11422
|
+
const shouldCaptureNodePreviewImage = useCallback11(
|
|
11423
|
+
(node) => {
|
|
11424
|
+
const minimizedDock = input.nodeDefinitionByType.get(node.data.typeId)?.window?.minimizedDock;
|
|
11425
|
+
return minimizedDock?.kind !== "component";
|
|
11426
|
+
},
|
|
11427
|
+
[input.nodeDefinitionByType]
|
|
11428
|
+
);
|
|
10308
11429
|
const resolveDockAnchorKey = useCallback11(
|
|
10309
11430
|
(node) => {
|
|
10310
11431
|
if (node.isMinimized && isWorkbenchMinimizedDockEligibleNode({
|
|
10311
11432
|
node,
|
|
10312
11433
|
nodeDefinitions: input.nodeDefinitionByType
|
|
10313
11434
|
})) {
|
|
11435
|
+
const snapshotNodes = input.hostSession.getSnapshot().nodes;
|
|
11436
|
+
const slotNodes = snapshotNodes.some(
|
|
11437
|
+
(snapshotNode) => snapshotNode.id === node.id
|
|
11438
|
+
) ? snapshotNodes.map(
|
|
11439
|
+
(snapshotNode) => snapshotNode.id === node.id ? node : snapshotNode
|
|
11440
|
+
) : [...snapshotNodes, node];
|
|
10314
11441
|
const minimizedAnchorKey = resolveWorkbenchMinimizedDockAnchorKeyForNode({
|
|
10315
11442
|
nodeId: node.id,
|
|
10316
11443
|
slots: resolveWorkbenchMinimizedDockSlots({
|
|
10317
11444
|
nodeDefinitions: input.nodeDefinitionByType,
|
|
10318
|
-
nodes:
|
|
11445
|
+
nodes: slotNodes
|
|
10319
11446
|
})
|
|
10320
11447
|
});
|
|
10321
11448
|
if (minimizedAnchorKey) {
|
|
@@ -10358,6 +11485,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
|
|
|
10358
11485
|
renderTopChrome,
|
|
10359
11486
|
renderWindowActions,
|
|
10360
11487
|
renderWindowHeader,
|
|
11488
|
+
shouldCaptureNodePreviewImage,
|
|
10361
11489
|
shouldKeepMinimizedNodeMounted,
|
|
10362
11490
|
resolveDockAnchorKey,
|
|
10363
11491
|
resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
|
|
@@ -10537,12 +11665,14 @@ function WorkbenchHost({
|
|
|
10537
11665
|
i18n,
|
|
10538
11666
|
layoutConstraints,
|
|
10539
11667
|
missionControl,
|
|
11668
|
+
minimizeAnimation,
|
|
10540
11669
|
nodes,
|
|
10541
11670
|
onDockEntryAction,
|
|
10542
11671
|
onDockEntryClick,
|
|
10543
11672
|
onHandleReady,
|
|
10544
11673
|
onLaunchRequest,
|
|
10545
11674
|
onMissionControlAdapterReady,
|
|
11675
|
+
onMissionControlRequestOpen,
|
|
10546
11676
|
onNodeCloseRequest,
|
|
10547
11677
|
projectedNodes,
|
|
10548
11678
|
renderBottomChrome,
|
|
@@ -10576,6 +11706,7 @@ function WorkbenchHost({
|
|
|
10576
11706
|
[contributions, dockEntries]
|
|
10577
11707
|
);
|
|
10578
11708
|
const missionControlMode = missionControl?.mode ?? null;
|
|
11709
|
+
const missionControlNodeIds = missionControl?.nodeIds;
|
|
10579
11710
|
const missionControlClose = missionControl?.onRequestClose ?? noop3;
|
|
10580
11711
|
const missionControlEnabled = missionControlMode !== null || onMissionControlAdapterReady !== void 0;
|
|
10581
11712
|
const {
|
|
@@ -10617,6 +11748,7 @@ function WorkbenchHost({
|
|
|
10617
11748
|
nodeDefinitionByType,
|
|
10618
11749
|
onDockEntryAction,
|
|
10619
11750
|
onDockEntryClick,
|
|
11751
|
+
onMissionControlRequestOpen,
|
|
10620
11752
|
renderBottomChrome,
|
|
10621
11753
|
renderTopChrome,
|
|
10622
11754
|
workspaceId
|
|
@@ -10624,6 +11756,7 @@ function WorkbenchHost({
|
|
|
10624
11756
|
const missionControlState = useWorkbenchMissionControlState({
|
|
10625
11757
|
adapter: missionControlAdapter,
|
|
10626
11758
|
mode: missionControlMode,
|
|
11759
|
+
nodeIds: missionControlNodeIds,
|
|
10627
11760
|
onRequestClose: missionControlClose
|
|
10628
11761
|
});
|
|
10629
11762
|
const missionControlPresence = useWorkbenchMissionControlPresence(missionControlState);
|
|
@@ -10639,6 +11772,7 @@ function WorkbenchHost({
|
|
|
10639
11772
|
interactive: !isHydrating,
|
|
10640
11773
|
layoutConstraints,
|
|
10641
11774
|
missionControlPhase: missionControlPresence.phase,
|
|
11775
|
+
minimizeAnimation,
|
|
10642
11776
|
presentation: missionControlState?.presentation ?? null,
|
|
10643
11777
|
renderBackdrop: missionControlRenderedState ? () => /* @__PURE__ */ jsx13(
|
|
10644
11778
|
WorkbenchMissionControlBackdrop,
|
|
@@ -10666,6 +11800,7 @@ function WorkbenchHost({
|
|
|
10666
11800
|
resolveFullscreenHeaderMode: surfaceRenderers.resolveFullscreenHeaderMode,
|
|
10667
11801
|
resolveDockAnchorKey: surfaceRenderers.resolveDockAnchorKey,
|
|
10668
11802
|
shortcutsEnabled,
|
|
11803
|
+
shouldCaptureNodePreviewImage: surfaceRenderers.shouldCaptureNodePreviewImage,
|
|
10669
11804
|
wallpaper,
|
|
10670
11805
|
windowChromeI18n,
|
|
10671
11806
|
windowChromeMode: surfaceRenderers.windowChromeMode
|