diff --git a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm index ba022e2b9..b2810f5d8 100644 --- a/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm +++ b/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.mm @@ -148,6 +148,18 @@ return; } +- (void)populateAllNodesFromNode:(nonnull NSString *)identifier inArray:(nonnull NSMutableArray *)mutableArray { + NSDictionary *nodeDict = [self getNode:identifier]; + if (nodeDict == nil) { + return; + } + [mutableArray addObject:nodeDict]; + NSArray *children = nodeDict[@"children"]; + for (NSString *childIdentifier in children) { + [self populateAllNodesFromNode:childIdentifier inArray:mutableArray]; + } +} + - (void)onCallGetAllNodesWithResponder:(nonnull id)responder { NSMutableArray *allNodes = @[].mutableCopy; NSString *identifier = [self trackObject: _rootNode]; @@ -216,11 +228,11 @@ const auto identifierForInvalidation = [descriptor identifierForInvalidation:node]; id nodeForInvalidation = [_trackedObjects objectForKey:identifierForInvalidation]; SKNodeDescriptor *descriptorForInvalidation = [_descriptorMapper descriptorForClass:[nodeForInvalidation class]]; - NSMutableArray *children = [self getChildrenForNode:nodeForInvalidation withDescriptor:descriptorForInvalidation]; updateDataForPath(value); - [connection send: @"invalidate" withParams: @{ - @"nodes": @[@{@"id": [descriptorForInvalidation identifierForNode: nodeForInvalidation], @"children": children}] - }]; + + NSMutableArray *nodesForInvalidation = [NSMutableArray new]; + [self populateAllNodesFromNode:[descriptorForInvalidation identifierForNode:nodeForInvalidation] inArray:nodesForInvalidation]; + [connection send: @"invalidateWithData" withParams: @{@"nodes": nodesForInvalidation}]; } } diff --git a/src/plugins/layout/Inspector.js b/src/plugins/layout/Inspector.js index 7faa68a38..83052c429 100644 --- a/src/plugins/layout/Inspector.js +++ b/src/plugins/layout/Inspector.js @@ -15,7 +15,7 @@ import {ElementsInspector} from 'flipper'; import {Component} from 'react'; import debounce from 'lodash.debounce'; -import type {PersistedState} from './'; +import type {PersistedState, ElementMap} from './'; type GetNodesOptions = { force?: boolean, @@ -45,6 +45,9 @@ export default class Inspector extends Component { GET_NODES: this.props.ax ? 'getAXNodes' : 'getNodes', SET_HIGHLIGHTED: 'setHighlighted', SELECT: this.props.ax ? 'selectAX' : 'select', + INVALIDATE_WITH_DATA: this.props.ax + ? 'invalidateWithDataAX' + : 'invalidateWithData', }; } @@ -113,6 +116,14 @@ export default class Inspector extends Component { }, ); + this.props.client.subscribe( + this.call().INVALIDATE_WITH_DATA, + (obj: {nodes: Array}) => { + const {nodes} = obj; + this.invalidateWithData(nodes); + }, + ); + this.props.client.subscribe( this.call().SELECT, ({path}: {path: Array}) => { @@ -159,6 +170,28 @@ export default class Inspector extends Component { } } + invalidateWithData(elements: Array): void { + if (elements.length === 0) { + return; + } + const updatedElements: ElementMap = elements.reduce( + (acc: ElementMap, element: Element) => { + acc[element.id] = { + ...element, + expanded: this.elements()[element.id]?.expanded, + }; + return acc; + }, + new Map(), + ); + this.props.setPersistedState({ + [this.props.ax ? 'AXelements' : 'elements']: { + ...this.elements(), + ...updatedElements, + }, + }); + } + invalidate(ids: Array): Promise> { if (ids.length === 0) { return Promise.resolve([]);