Fix Focus mode bug when is the decendant of an inactive node.

Summary: If you focus a node and then move activity then the focused nodes will no longer be active. this means that they are automatically collapsed in the tree and the visualizer wont be display it. Previously we didnt spot this and the focus state was wrong. Now we check that all parents are active whenever an update comes from client, if the focused node is no longer active after an update then we remove the focus

Reviewed By: lblasa

Differential Revision: D41548250

fbshipit-source-id: d536e0c466d9002fc53bcb43b9b29c7c7fa23ad2
This commit is contained in:
Luke De Feo
2022-11-28 05:09:20 -08:00
committed by Facebook GitHub Bot
parent 8eb0866760
commit d9314c3b73

View File

@@ -12,6 +12,7 @@ import {
createState,
createDataSource,
produce,
Atom,
} from 'flipper-plugin';
import {
Events,
@@ -107,6 +108,7 @@ export function plugin(client: PluginClient<Events>) {
});
nodes.set(liveClientData.nodes);
snapshot.set(liveClientData.snapshotInfo);
checkFocusedNodeStillActive(uiState, nodes.get());
}
};
@@ -151,6 +153,8 @@ export function plugin(client: PluginClient<Events>) {
if (!uiState.isPaused.get()) {
nodes.set(liveClientData.nodes);
snapshot.set(liveClientData.snapshotInfo);
checkFocusedNodeStillActive(uiState, nodes.get());
}
});
@@ -180,6 +184,52 @@ function setParentPointers(
});
}
function checkFocusedNodeStillActive(
uiState: {
isPaused: Atom<boolean>;
searchTerm: Atom<string>;
isContextMenuOpen: Atom<boolean>;
hoveredNodes: Atom<Id[]>;
focusedNode: Atom<Id | undefined>;
treeState: Atom<TreeState>;
},
nodes: Map<Id, UINode>,
) {
const focusedNodeId = uiState.focusedNode.get();
const focusedNode = focusedNodeId && nodes.get(focusedNodeId);
if (focusedNode && !isFocusedNodeAncestryAllActive(focusedNode, nodes)) {
uiState.focusedNode.set(undefined);
}
}
function isFocusedNodeAncestryAllActive(
focused: UINode,
nodes: Map<Id, UINode>,
): boolean {
let node = focused;
while (node != null) {
if (node.parent == null) {
return true;
}
const parent = nodes.get(node.parent);
if (parent == null) {
//should also never happen
return false;
}
if (parent.activeChild != null && parent.activeChild !== node.id) {
return false;
}
node = parent;
}
//wont happen
return false;
}
function collapseinActiveChildren(node: UINode, draft: TreeState) {
if (node.activeChild) {
const inactiveChildren = node.children.filter(