Nested node structure for vizualiser
Summary: This structure makes sense for the vizualiser which itself is a nested structure. It also saves the awkward branch of there is no key in the map. Reviewed By: lblasa Differential Revision: D40670371 fbshipit-source-id: 6c1b960a77749be9e8a193decf6b8d50ce6c7968
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1398e2aa8a
commit
bfe098485f
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Id, Snapshot, Tag, UINode} from '../types';
|
import {Id, NestedNode, Snapshot, Tag, UINode} from '../types';
|
||||||
import {styled, Layout, theme} from 'flipper-plugin';
|
import {styled, Layout, theme} from 'flipper-plugin';
|
||||||
|
|
||||||
export const Visualization2D: React.FC<
|
export const Visualization2D: React.FC<
|
||||||
@@ -33,12 +33,16 @@ export const Visualization2D: React.FC<
|
|||||||
modifierPressed,
|
modifierPressed,
|
||||||
}) => {
|
}) => {
|
||||||
//todo, do a bfs search for the first bounds found
|
//todo, do a bfs search for the first bounds found
|
||||||
const rootBounds = nodes.get(rootId)?.bounds;
|
|
||||||
const rootSnapshot = snapshots.get(rootId);
|
|
||||||
|
|
||||||
if (!rootBounds) {
|
const rootSnapshot = snapshots.get(rootId);
|
||||||
|
const root = toNestedNode(rootId, nodes);
|
||||||
|
|
||||||
|
if (!root) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rootBounds = root.bounds;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onMouseLeave={(e) => {
|
onMouseLeave={(e) => {
|
||||||
@@ -66,8 +70,7 @@ export const Visualization2D: React.FC<
|
|||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<Visualization2DNode
|
<Visualization2DNode
|
||||||
nodeId={rootId}
|
node={root}
|
||||||
nodes={nodes}
|
|
||||||
snapshots={snapshots}
|
snapshots={snapshots}
|
||||||
hoveredNode={hoveredNode}
|
hoveredNode={hoveredNode}
|
||||||
selectedNode={selectedNode}
|
selectedNode={selectedNode}
|
||||||
@@ -80,9 +83,7 @@ export const Visualization2D: React.FC<
|
|||||||
};
|
};
|
||||||
|
|
||||||
function Visualization2DNode({
|
function Visualization2DNode({
|
||||||
parentId,
|
node,
|
||||||
nodeId,
|
|
||||||
nodes,
|
|
||||||
snapshots,
|
snapshots,
|
||||||
hoveredNode,
|
hoveredNode,
|
||||||
selectedNode,
|
selectedNode,
|
||||||
@@ -90,9 +91,7 @@ function Visualization2DNode({
|
|||||||
onHoverNode,
|
onHoverNode,
|
||||||
modifierPressed,
|
modifierPressed,
|
||||||
}: {
|
}: {
|
||||||
nodeId: Id;
|
node: NestedNode;
|
||||||
parentId?: Id;
|
|
||||||
nodes: Map<Id, UINode>;
|
|
||||||
snapshots: Map<Id, Snapshot>;
|
snapshots: Map<Id, Snapshot>;
|
||||||
modifierPressed: boolean;
|
modifierPressed: boolean;
|
||||||
hoveredNode?: Id;
|
hoveredNode?: Id;
|
||||||
@@ -100,38 +99,31 @@ function Visualization2DNode({
|
|||||||
onSelectNode: (id?: Id) => void;
|
onSelectNode: (id?: Id) => void;
|
||||||
onHoverNode: (id?: Id) => void;
|
onHoverNode: (id?: Id) => void;
|
||||||
}) {
|
}) {
|
||||||
const node = nodes.get(nodeId);
|
const snapshot = snapshots.get(node.id);
|
||||||
const snapshot = snapshots.get(nodeId);
|
|
||||||
|
|
||||||
if (!node) {
|
const isHovered = hoveredNode === node.id;
|
||||||
return null;
|
const isSelected = selectedNode === node.id;
|
||||||
}
|
|
||||||
|
|
||||||
const isHovered = hoveredNode === nodeId;
|
let nestedChildren: NestedNode[];
|
||||||
const isSelected = selectedNode === nodeId;
|
|
||||||
|
|
||||||
let childrenIds: Id[] = [];
|
|
||||||
|
|
||||||
//if there is an active child don't draw the other children
|
//if there is an active child don't draw the other children
|
||||||
//this means we don't draw overlapping activities / tabs etc
|
//this means we don't draw overlapping activities / tabs etc
|
||||||
if (node.activeChild) {
|
if (node.activeChildIdx) {
|
||||||
childrenIds = [node.activeChild];
|
nestedChildren = [node.children[node.activeChildIdx]];
|
||||||
} else {
|
} else {
|
||||||
childrenIds = node.children;
|
nestedChildren = node.children;
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop drawing children if hovered with the modifier so you
|
// stop drawing children if hovered with the modifier so you
|
||||||
// can see parent views without their children getting in the way
|
// can see parent views without their children getting in the way
|
||||||
if (isHovered && modifierPressed) {
|
if (isHovered && modifierPressed) {
|
||||||
childrenIds = [];
|
nestedChildren = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const children = childrenIds.map((childId) => (
|
const children = nestedChildren.map((child) => (
|
||||||
<Visualization2DNode
|
<Visualization2DNode
|
||||||
parentId={nodeId}
|
key={child.id}
|
||||||
key={childId}
|
node={child}
|
||||||
nodeId={childId}
|
|
||||||
nodes={nodes}
|
|
||||||
snapshots={snapshots}
|
snapshots={snapshots}
|
||||||
hoveredNode={hoveredNode}
|
hoveredNode={hoveredNode}
|
||||||
onSelectNode={onSelectNode}
|
onSelectNode={onSelectNode}
|
||||||
@@ -161,11 +153,11 @@ function Visualization2DNode({
|
|||||||
}}
|
}}
|
||||||
onMouseEnter={(e) => {
|
onMouseEnter={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
onHoverNode(nodeId);
|
onHoverNode(node.id);
|
||||||
}}
|
}}
|
||||||
onMouseLeave={(e) => {
|
onMouseLeave={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
onHoverNode(parentId);
|
// onHoverNode(parentId);
|
||||||
}}
|
}}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -232,3 +224,30 @@ const OuterBorder = styled.div({
|
|||||||
function toPx(n: number) {
|
function toPx(n: number) {
|
||||||
return `${n / 2}px`;
|
return `${n / 2}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toNestedNode(
|
||||||
|
rootId: Id,
|
||||||
|
nodes: Map<Id, UINode>,
|
||||||
|
): NestedNode | undefined {
|
||||||
|
function uiNodeToNestedNode(node: UINode): NestedNode {
|
||||||
|
const activeChildIdx = node.activeChild
|
||||||
|
? node.children.indexOf(node.activeChild)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: node.id,
|
||||||
|
name: node.name,
|
||||||
|
attributes: node.attributes,
|
||||||
|
children: node.children
|
||||||
|
.map((childId) => nodes.get(childId))
|
||||||
|
.filter((child) => child != null)
|
||||||
|
.map((child) => uiNodeToNestedNode(child!!)),
|
||||||
|
bounds: node.bounds,
|
||||||
|
tags: node.tags,
|
||||||
|
activeChildIdx: activeChildIdx,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = nodes.get(rootId);
|
||||||
|
return root ? uiNodeToNestedNode(root) : undefined;
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,6 +50,16 @@ export type UpdateMetadataEvent = {
|
|||||||
attributeMetadata: Record<MetadataId, Metadata>;
|
attributeMetadata: Record<MetadataId, Metadata>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type NestedNode = {
|
||||||
|
id: Id;
|
||||||
|
name: string;
|
||||||
|
attributes: Record<string, Inspectable>;
|
||||||
|
children: NestedNode[];
|
||||||
|
bounds: Bounds;
|
||||||
|
tags: Tag[];
|
||||||
|
activeChildIdx?: number;
|
||||||
|
};
|
||||||
|
|
||||||
export type UINode = {
|
export type UINode = {
|
||||||
id: Id;
|
id: Id;
|
||||||
qualifiedName: string;
|
qualifiedName: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user