UI preview of selected element

Summary:
This is a prototype for view preview within Flipper for iOS (Android next).

If enabled, a preview of the selected element is rendered in the attribute inspector.

Changelog: Add view preview/snapshot for the Layout plugin on iOS.

Reviewed By: antonk52

Differential Revision: D34990372

fbshipit-source-id: 1984514fbf59041ad236008a8db10569c5fc5f94
This commit is contained in:
Lorenzo Blasa
2022-03-28 05:17:23 -07:00
committed by Facebook GitHub Bot
parent c662f3679d
commit aed7e7e6f2
10 changed files with 188 additions and 15 deletions

View File

@@ -18,7 +18,7 @@ import {
Logger,
} from 'flipper';
import {Panel} from 'flipper-plugin';
import {PureComponent} from 'react';
import {PureComponent, useState} from 'react';
import React from 'react';
import {useMemo, useEffect} from 'react';
import {kebabCase} from 'lodash';
@@ -85,11 +85,19 @@ type Props = {
client: PluginClient;
realClient: Client;
logger: Logger;
inSnapshotMode: boolean;
};
type ElementSnapshot = {
element: Element | null;
snapshot: String | null;
};
const Sidebar: React.FC<Props> = (props: Props) => {
const {element} = props;
const [elementSnapshot, setElementSnapshot] = useState<ElementSnapshot>();
const [sectionDefs, sectionKeys] = useMemo(() => {
const sectionKeys = [];
const sectionDefs = [];
@@ -135,7 +143,36 @@ const Sidebar: React.FC<Props> = (props: Props) => {
return [sectionDefs, sectionKeys];
}, [element]);
const sections: Array<React.ReactNode> = (
useEffect(() => {
if (
props.inSnapshotMode &&
(!elementSnapshot || elementSnapshot.element != element)
) {
props.client
.call('getSnapshot', {
id: props.element?.id,
name: props.element?.name,
})
.then((response) => {
setElementSnapshot({element: element, snapshot: response.snapshot});
})
.catch((e) => {
console.log(
'ElementsInspector unable to obtain screenshot for the selected item',
e,
);
});
}
}, [
element,
elementSnapshot,
props.client,
props.element?.id,
props.element?.name,
props.inSnapshotMode,
]);
const sidebarExtensions =
(SidebarExtensions &&
element?.data &&
Object.entries(SidebarExtensions).map(([ext, Comp]) => (
@@ -147,18 +184,32 @@ const Sidebar: React.FC<Props> = (props: Props) => {
selectedNode={element}
/>
))) ||
[]
).concat(
sectionDefs.map((def) => (
<InspectorSidebarSection
tooltips={props.tooltips}
key={def.key}
id={def.id}
data={def.data}
onValueChanged={props.onValueChanged}
/>
)),
);
[];
const sidebarInspector = sectionDefs.map((def) => (
<InspectorSidebarSection
tooltips={props.tooltips}
key={def.key}
id={def.id}
data={def.data}
onValueChanged={props.onValueChanged}
/>
));
const sidebarPreview =
props.inSnapshotMode && elementSnapshot?.snapshot ? (
<Panel key="preview" title="Preview" pad>
<img
style={{
display: 'block',
marginLeft: 'auto',
marginRight: 'auto',
width: '100%',
}}
src={'data:image/png;base64,' + elementSnapshot?.snapshot}
/>
</Panel>
) : null;
useEffect(() => {
sectionKeys.map((key) =>
@@ -169,7 +220,13 @@ const Sidebar: React.FC<Props> = (props: Props) => {
if (!element || !element.data) {
return <NoData grow>No data</NoData>;
}
return <>{sections}</>;
return (
<>
{sidebarExtensions}
{sidebarInspector}
{sidebarPreview}
</>
);
};
export default Sidebar;