Add survey banner for Hermes Debugger

Summary:
As requested by the Hermes team, this adds an internal-only banner linking to a survey for the debugger (controlled by a GK).

Gatekeeper: https://our.intern.facebook.com/intern/gatekeeper/projects/flipper_plugin_hermes_debugger_survey/

Reviewed By: mweststrate

Differential Revision: D21556848

fbshipit-source-id: df34f49f504d11bba622709df86c8475be2433eb
This commit is contained in:
Rick Hanlon
2020-05-15 05:16:34 -07:00
committed by Facebook GitHub Bot
parent e23acc6f04
commit e3202dfb35
3 changed files with 150 additions and 9 deletions

View File

@@ -0,0 +1,80 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import React from 'react';
import {shell} from 'electron';
import {styled, colors, FlexRow, Text, GK} from 'flipper';
const BannerContainer = styled(FlexRow)({
height: '30px',
width: '100%',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#2bb673', // Hermes green.
});
const BannerText = styled(Text)({
color: colors.white,
fontSize: 14,
lineHeight: '20px',
});
const BannerLink = styled(CustomLink)({
color: colors.white,
textDecoration: 'underline',
'&:hover': {
cursor: 'pointer',
color: '#303846',
},
});
const StyledLink = styled.span({
'&:hover': {
cursor: 'pointer',
},
});
StyledLink.displayName = 'CustomLink:StyledLink';
function CustomLink(props: {
href: string;
className?: string;
children?: React.ReactNode;
style?: React.CSSProperties;
}) {
return (
<StyledLink
className={props.className}
onClick={() => shell.openExternal(props.href)}
style={props.style}>
{props.children || props.href}
</StyledLink>
);
}
export const isBannerEnabled: () => boolean = function () {
return GK.get('flipper_plugin_hermes_debugger_survey');
};
export default function Banner() {
if (!GK.get('flipper_plugin_hermes_debugger_survey')) {
return null;
}
return (
<BannerContainer>
<BannerText>
Help us improve your debugging experience with this{' '}
<BannerLink href="https://fburl.com/hermessurvey">
single page survey
</BannerLink>
!
</BannerText>
</BannerContainer>
);
}

View File

@@ -8,6 +8,7 @@
*/
import React from 'react';
import {styled, colors, FlexColumn} from 'flipper';
import electron from 'electron';
@@ -17,7 +18,10 @@ const devToolsNodeId = (url: string) =>
// TODO: build abstractionf or this: T62306732
const TARGET_CONTAINER_ID = 'flipper-out-of-contents-container'; // should be a hook in the future
function createDevToolsNode(url: string): HTMLElement {
function createDevToolsNode(
url: string,
marginTop: string | null,
): HTMLElement {
const existing = findDevToolsNode(url);
if (existing) {
return existing;
@@ -40,6 +44,11 @@ function createDevToolsNode(url: string): HTMLElement {
iframe.src = url.replace(/^chrome-/, '');
wrapper.appendChild(iframe);
if (marginTop) {
document.getElementById(TARGET_CONTAINER_ID)!.style.marginTop = marginTop;
}
document.getElementById(TARGET_CONTAINER_ID)!.appendChild(wrapper);
return wrapper;
}
@@ -61,15 +70,24 @@ function detachDevTools(devToolsNode: HTMLElement | null) {
}
}
const EmptyContainer = styled(FlexColumn)({
height: '100%',
width: '100%',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: colors.light02,
});
type ChromeDevToolsProps = {
url: string;
marginTop: string | null;
};
export default class ChromeDevTools extends React.Component<
ChromeDevToolsProps
> {
createDevTools(url: string) {
const devToolsNode = createDevToolsNode(url);
createDevTools(url: string, marginTop: string | null) {
const devToolsNode = createDevToolsNode(url, marginTop);
attachDevTools(devToolsNode);
}
@@ -78,7 +96,7 @@ export default class ChromeDevTools extends React.Component<
}
componentDidMount() {
this.createDevTools(this.props.url);
this.createDevTools(this.props.url, this.props.marginTop);
}
componentWillUnmount() {
@@ -90,11 +108,11 @@ export default class ChromeDevTools extends React.Component<
const newUrl = this.props.url;
if (oldUrl != newUrl) {
this.hideDevTools(oldUrl);
this.createDevTools(newUrl);
this.createDevTools(newUrl, this.props.marginTop);
}
}
render() {
return <div style={{height: 0}} />;
return <EmptyContainer />;
}
}

View File

@@ -8,8 +8,16 @@
*/
import React from 'react';
import {FlipperDevicePlugin, Device} from 'flipper';
import {
FlipperDevicePlugin,
Device,
styled,
colors,
FlexRow,
FlexColumn,
} from 'flipper';
import LaunchScreen from './LaunchScreen';
import Banner, {isBannerEnabled} from './Banner';
import SelectScreen from './SelectScreen';
import ErrorScreen from './ErrorScreen';
import ChromeDevTools from './ChromeDevTools';
@@ -36,6 +44,22 @@ type State = Readonly<{
error?: Error | null;
}>;
const Content = styled(FlexRow)({
height: '100%',
width: '100%',
flexGrow: 1,
justifyContent: 'center',
alignItems: 'center',
});
const Container = styled(FlexColumn)({
height: '100%',
width: '100%',
justifyContent: 'flex-start',
alignItems: 'flex-start',
backgroundColor: colors.light02,
});
export default class extends FlipperDevicePlugin<State, any, any> {
static title = 'Hermes Debugger';
static id = 'Hermesdebuggerrn';
@@ -117,11 +141,21 @@ export default class extends FlipperDevicePlugin<State, any, any> {
handleSelect = (selectedTarget: Target) => this.setState({selectedTarget});
render() {
renderContent() {
const {error, selectedTarget, targets} = this.state;
if (selectedTarget) {
return <ChromeDevTools url={selectedTarget.devtoolsFrontendUrl} />;
let bannerMargin = null;
if (isBannerEnabled()) {
bannerMargin = '29px';
}
return (
<ChromeDevTools
url={selectedTarget.devtoolsFrontendUrl}
marginTop={bannerMargin}
/>
);
} else if (targets != null && targets.length === 0) {
return <LaunchScreen />;
} else if (targets != null && targets.length > 0) {
@@ -132,4 +166,13 @@ export default class extends FlipperDevicePlugin<State, any, any> {
return null;
}
}
render() {
return (
<Container>
<Banner />
<Content>{this.renderContent()}</Content>
</Container>
);
}
}